Register file extension

For one project I needed to create an association between files and programs. It does not matter, if it’s some new extension like .myextension or you want to override the opening .mp3 for your program. It is clear that you do not want to mystify users by running unfamiliar and specific applications to open computer file in a specific way, or run the reg file. Everything should be done programmatically, as desired, or to offer to reassign him to open the files by default with your program.

Thus, the aim – to register programmatically on any extension of your program.

Search the Internet gives mainly links to an articlehttp://www.codeproject.com/KB/dotnet/System_File_Association.aspx where there is a library for working with the registration of extensions. After downloading the library, I saw how big it is and monstrous, and decided to write my own, small and simpler, otherwise I’m getting mixed up in such an abundance of all in provided lib on CodeProject =)

The actual work

In. Net is nothing ready to register the extension on the application. But you can repeat the code the way it is contained in the system. Here are the most common form of registration application for extension with reg file.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.myextension]
@="app.myextension"

[HKEY_CLASSES_ROOT\app.myextension]
@="Text Document"

[HKEY_CLASSES_ROOT\app.myextension\DefaultIcon]
@="%SystemRoot%\\SysWow64\\imageres.dll,-102"

[HKEY_CLASSES_ROOT\app.myextension\shell]

[HKEY_CLASSES_ROOT\app.myextension\shell\open]

[HKEY_CLASSES_ROOT\app.myextension\shell\open\command]
@="%SystemRoot%\\System32\\notepad.exe" \"%1\""

[HKEY_CLASSES_ROOT\app.myextension\shell\print]

[HKEY_CLASSES_ROOT\app.myextension\shell\print\command]
@="%SystemRoot%\\System32\\notepad.exe" /p \"%1\""

So you should get two branches. % 1 – is a pointer to the selected file.

This code illustrates the case when you set the association for all users on the computer, and for that you will need administrator’s rights. In order to establish an association for a single user to add data to the HKEY_CURRENT_USER\Software\Classes – for this needs customary rights enforcement.

If you have a unique extension and registration will take place during the installation, it is best to use the properties of the installer and ask all associations there. This we will shall discuss later on, when we look at the installer base in detail.

Implementation

In fact, it is only necessary to write data to the registry. Another question is how to do it beautifully! =)

I think it would be useful to have a structure that will contain all the necessary data for creating the association. We will need:

  • Application name
  • The path to the application
  • The path to icon (can be a way to the application, if you do not specify otherwise)
  • Extension name
  • A set of actions with the file

So class resembles the following:

public class FileAssociateInfo {
   public string ApplicationName;
   public string ApplicationPath;
   public string ApplicationIconPath;
   private string fileExtension;
   public string FileExtension {
      get { return fileExtension; }
      set { fileExtension = FormatExtension(value); }
   }

   public string RegMarker {
      get { return string.Format("{0}{1}", ApplicationName, FileExtension); }
   }

   public List<FileAction> FileActions = new List<FileAction>();

   private static string FormatExtension(string info) {
      return info.StartsWith(".") ? info : "." + info;
   }
}

A set of actions with the file, it appears here too as a class. Since according to the reg file you must specify a command name and command itself. This class might look like this:

public class FileAction {
   public string Name;
   public string Command;
}

Very easy! =)

May of course in me is too much love to all kinds of special classes, but here I finished the one relatively small class of buildings FileAssociateInfo.

FileAssociateInfoBuilder will create all the necessary data. In my view the final code became better.

So it became possible to write

var builder = new FileAssociateInfoBuilder("vt_notepad", @"c:\Windows\System32\notepad.exe")
      .AddCommand("Open", "", PassSelectedFile.ToApplication)
      .AddExtension(extension);

In the constructor goes the name of the application, the path before him, and then given the command, indicating the file or not. In the process I thought it was possible to make the possibility of adding a few extensions, but still refused it.

PassSelectedFile is an enumerator , which indicates the transferred file or not.

public enum PassSelectedFile {
    ToApplication,
    Nowhere
}

It seems to me the name and value is quite authentic! ;)

Builder is too easy; I hope that for you as well.

public class FileAssociateInfoBuilder {
   private readonly string applicationPath;
   private readonly FileAssociateInfo fileAssociateInfo;

   public FileAssociateInfoBuilder(string applicationName, string applicationPath) {
      this.applicationPath = applicationPath;
      fileAssociateInfo = new FileAssociateInfo {
            ApplicationName = applicationName,
            ApplicationPath = applicationPath,
            ApplicationIconPath = applicationPath,
      };
   }

   public FileAssociateInfoBuilder AddExtension(string extension) {
      fileAssociateInfo.FileExtension = extension;
      return this;
   }

   public FileAssociateInfoBuilder AddCommand(string commandName, string arg, PassSelectedFile argValue) {
      fileAssociateInfo.FileActions.Add(new FileAction {
             Name = commandName,
             Command = string.Format("\"{0}\" {1} {2}",
                      applicationPath,
                      arg,
                      argValue == PassSelectedFile.ToApplication ? "\"%1\"" : "")
             });
      return this;
   }

   public FileAssociateInfo Result() {
      return fileAssociateInfo;
   }
}

After that you can go to the most important class, the service which will create all the keys in the registry.

Actually the creation of keys

public void CreateAssociation(FileAssociateInfo info) {
   if(Exists(info.FileExtension)) return;

    var classes = Registry.CurrentUser.CreateSubKey("Software\\Classes");
    classes.CreateSubKey(info.FileExtension).SetValue("", info.RegMarker);

    var mainKey = classes.CreateSubKey(info.RegMarker);
    mainKey.SetValue("", string.Format("{0} files", info.ApplicationName));
    mainKey.CreateSubKey("DefaultIcon").SetValue("", info.ApplicationIconPath);

    var shell = mainKey.CreateSubKey("Shell");

    info.FileActions.ForEach(action => {
          var command = shell.CreateSubKey(action.Name);
          command.SetValue("", action.Name);
          command.CreateSubKey("Command").SetValue("", action.Command);
        }
    );
}

There is nothing supernatural, no rocket-science, just consistently creates a key in the registry. Immediately after that, everything will work.

Removing it will take more than just necessary to know the expansion and all. The rest
can be calculated.

public void DeleteAssociation(string fileExtension) {
    var classes = Registry.CurrentUser.CreateSubKey("Software\\Classes");

    var mainKey = classes.CreateSubKey(fileExtension).GetValue("").ToString();

    classes.DeleteSubKeyTree(fileExtension);
    classes.DeleteSubKeyTree(mainKey);
}

At this all the main code is complete.

The only thing you need to pass the input parameter, if you want this functionality to your programs.

Evolving

You can make checks on the existence of a registered extension. You can get all the extensions in the system. You can create your own steps to absolutely all of the files, if the finish for the expansion of “*”. If you are not lazy, you can make a service that will do the registration, depending on user privileges, ie, or for all users if the administrator rights, or only for one user.

In general, the technology and knowledge will be very useful in future articles. So,be aware of)

Source Code

Hard’n’heavy!

Tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>