How to associate file extension with current executable in C #

I would like to associate the file extension with the current executable in C #. Thus, when the user clicks on the file later in Explorer, it launches my executable file with the given file as the first argument. Ideally, he also set the icon for the specified file extensions to the icon of my executable file. Thanks to everyone.

+45
c # windows winforms
Sep 16 '08 at 6:18
source share
9 answers

There is no .Net API for directly managing file associations, but you can use registry classes to read and write keys that you need.

You need to create a key under HKEY_CLASSES_ROOT with the name set for the extension of your file (for example: ".txt"). Set the default value of this key to a unique name for your file type, for example, "Acme.TextFile". Then create another key under HKEY_CLASSES_ROOT with the name set to "Acme.TextFile". Add the "DefaultIcon" subkey and set the default value for the file containing the icon that you want to use for this file type. Add another brother called a "shell." Under the shell key, add a key for each action that you want to get through the Explorer context menu, setting the default value for each key to the path to the executable file, and then a space and "% 1" to represent the path to the selected file .

For example, here is an example registry file for creating a link between TXT files and EmEditor:

 Windows Registry Editor Version 5.00

 [HKEY_CLASSES_ROOT \ .txt]
 @ = "emeditor.txt"

 [HKEY_CLASSES_ROOT \ emeditor.txt]
 @ = "Text Document"

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

 [HKEY_CLASSES_ROOT \ emeditor.txt \ shell]

 [HKEY_CLASSES_ROOT \ emeditor.txt \ shell \ open]

 [HKEY_CLASSES_ROOT \ emeditor.txt \ shell \ open \ command]
 @ = "\" C: \\ Program Files \\ EmEditor \\ EMEDITOR.EXE \ "\"% 1 \ ""

 [HKEY_CLASSES_ROOT \ emeditor.txt \ shell \ print]

 [HKEY_CLASSES_ROOT \ emeditor.txt \ shell \ print \ command]
 @ = "\" C: \\ Program Files \\ EmEditor \\ EMEDITOR.EXE \ "/ p \"% 1 \ ""
+38
Sep 16 '08 at 6:34
source share

Also, if you decide to go to the registry, remember that current user associations are under HKEY_CURRENT_USER \ Software \ Classes . It might be better to add your application instead of local classes.

If your program is launched by a limited user, you still cannot modify CLASSES_ROOT.

+25
Sep 16 '08 at 6:40
source share

If you use ClickOnce deployment, all this is handled for you (at least in VS2008 SP1); simply:

  • Project properties
  • Publish
  • Options
  • File associatons
  • (add everything you need)

(note that this must be full trust, designed for .NET 3.5, and must be installed for offline use)

See also MSDN: How to Create File Associations for a ClickOnce Application

+11
Aug 25 '09 at 10:17
source share

Here is a complete example:

public class FileAssociation { public string Extension { get; set; } public string ProgId { get; set; } public string FileTypeDescription { get; set; } public string ExecutableFilePath { get; set; } } public class FileAssociations { // needed so that Explorer windows get refreshed after the registry is updated [System.Runtime.InteropServices.DllImport("Shell32.dll")] private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2); private const int SHCNE_ASSOCCHANGED = 0x8000000; private const int SHCNF_FLUSH = 0x1000; public static void EnsureAssociationsSet() { var filePath = Process.GetCurrentProcess().MainModule.FileName; EnsureAssociationsSet( new FileAssociation { Extension = ".binlog", ProgId = "MSBuildBinaryLog", FileTypeDescription = "MSBuild Binary Log", ExecutableFilePath = filePath }, new FileAssociation { Extension = ".buildlog", ProgId = "MSBuildStructuredLog", FileTypeDescription = "MSBuild Structured Log", ExecutableFilePath = filePath }); } public static void EnsureAssociationsSet(params FileAssociation[] associations) { bool madeChanges = false; foreach (var association in associations) { madeChanges |= SetAssociation( association.Extension, association.ProgId, association.FileTypeDescription, association.ExecutableFilePath); } if (madeChanges) { SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero); } } public static bool SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath) { bool madeChanges = false; madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + extension, progId); madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription); madeChanges |= SetKeyDefaultValue($@"Software\Classes\{progId}\shell\open\command", "\"" + applicationFilePath + "\" \"%1\""); return madeChanges; } private static bool SetKeyDefaultValue(string keyPath, string value) { using (var key = Registry.CurrentUser.CreateSubKey(keyPath)) { if (key.GetValue(null) as string != value) { key.SetValue(null, value); return true; } } return false; } 
+8
Jun 29 '17 at 5:20
source share

There may be specific reasons why you do not want to use the installation package for your project, but the installation package is a great place to easily perform application configuration tasks, such as registering file extensions, adding shortcuts to the desktop, etc.

Here's how to create a file extension association using Visual Studio's built-in installation tools:

  • As part of an existing C # solution, add a new project and select the project type as Other Project Types β†’ Setup and Deployment β†’ Setup Project (or try the Setup Wizard)

  • Configure your installer (this requires many existing documents if you need help)

  • Right-click the installation project in the solution explorer, select View β†’ File Types , and then add the extension that you want to register with the program to start it.

This method has the added benefit of cleaning up after itself if the user launches a deletion for your application.

+7
May 22 '09 at 18:41
source share

To learn about the Windows Registry method:

I create keys under HKEY_CURRENT_USER \ Software \ Classes (e.g. Ishmaeel said)

and follow the instructions of X-Cubed.

An example code looks like this:

 private void Create_abc_FileAssociation() { /***********************************/ /**** Key1: Create ".abc" entry ****/ /***********************************/ Microsoft.Win32.RegistryKey key1 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true); key1.CreateSubKey("Classes"); key1 = key1.OpenSubKey("Classes", true); key1.CreateSubKey(".abc"); key1 = key1.OpenSubKey(".abc", true); key1.SetValue("", "DemoKeyValue"); // Set default key value key1.Close(); /*******************************************************/ /**** Key2: Create "DemoKeyValue\DefaultIcon" entry ****/ /*******************************************************/ Microsoft.Win32.RegistryKey key2 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true); key2.CreateSubKey("Classes"); key2 = key2.OpenSubKey("Classes", true); key2.CreateSubKey("DemoKeyValue"); key2 = key2.OpenSubKey("DemoKeyValue", true); key2.CreateSubKey("DefaultIcon"); key2 = key2.OpenSubKey("DefaultIcon", true); key2.SetValue("", "\"" + "(The icon path you desire)" + "\""); // Set default key value key2.Close(); /**************************************************************/ /**** Key3: Create "DemoKeyValue\shell\open\command" entry ****/ /**************************************************************/ Microsoft.Win32.RegistryKey key3 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true); key3.CreateSubKey("Classes"); key3 = key3.OpenSubKey("Classes", true); key3.CreateSubKey("DemoKeyValue"); key3 = key3.OpenSubKey("DemoKeyValue", true); key3.CreateSubKey("shell"); key3 = key3.OpenSubKey("shell", true); key3.CreateSubKey("open"); key3 = key3.OpenSubKey("open", true); key3.CreateSubKey("command"); key3 = key3.OpenSubKey("command", true); key3.SetValue("", "\"" + "(The application path you desire)" + "\"" + " \"%1\""); // Set default key value key3.Close(); } 

Just show you guys a quick demo, very easy to understand. You can change these key values, and everything will be fine.

+5
Feb 18 '15 at 14:25
source share

File associations are defined in the registry under HKEY_CLASSES_ROOT.

Here is an example of VB.NET here that I can easily port to C #.

+2
Sep 16 '08 at 6:28
source share

There are two cmd tools that have been around since Windows 7 that make it easy to create simple file associations. They are Assoc and FType . Here is a basic explanation of each team.

  • Assoc - Associates a file extension (for example, ".txt") with a "file type".
  • FType - defines the executable file to run when the user opens this type of file.

Please note that these are cmd tools, not executable files (exe). This means that they can only be run in the CMD window or using ShellExecute with the cmd / c component. You can learn more about them through the links or by typing "assoc /?" and "ftype /?" at the cmd command prompt.

So, to associate the application with the .bob extension, you can open the cmd window (WindowKey + R, type cmd, press enter) and do the following:

 assoc .bob=BobFile ftype BobFile=c:\temp\BobView.exe "%1" 

This is much easier than messing with the registry, and most likely it will work in a future version of Windows.

Combining it, here is the C # function for creating file associations:

 public static int setFileAssociation(string[] extensions, string fileType, string openCommandString) { int v = execute("cmd", "/c ftype " + fileType + "=" + openCommandString); foreach (string ext in extensions) { v = execute("cmd", "/c assoc " + ext + "=" + fileType); if (v != 0) return v; } return v; } public static int execute(string exeFilename, string arguments) { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = false; startInfo.UseShellExecute = true; startInfo.FileName = exeFilename; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.Arguments = arguments; try { using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); return exeProcess.ExitCode; } } catch { return 1; } } 
0
Oct 23 '17 at 23:47 on
source share

Below is the code that should work, it adds the necessary values ​​to the Windows registry. I usually run SelfCreateAssociation (". Abc") in my executable. (form constructor or onload or onshown) It will update the registry entry for the current user, every time the executable is executed. (useful for debugging if you have some changes). If you need detailed information about its associated registry keys, check out this MSDN link.

https://msdn.microsoft.com/en-us/library/windows/desktop/dd758090(v=vs.85).aspx

Get more information about the ClassesRoot registry key. See MSDN Article.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724475(v=vs.85).aspx

 public enum KeyHiveSmall { ClassesRoot, CurrentUser, LocalMachine, } /// <summary> /// Create an associaten for a file extension in the windows registry /// CreateAssociation(@"vendor.application",".tmf","Tool file",@"C:\Windows\SYSWOW64\notepad.exe",@"%SystemRoot%\SYSWOW64\notepad.exe,0"); /// </summary> /// <param name="ProgID">eg vendor.application</param> /// <param name="extension">eg .tmf</param> /// <param name="description">eg Tool file</param> /// <param name="application">eg @"C:\Windows\SYSWOW64\notepad.exe"</param> /// <param name="icon">@"%SystemRoot%\SYSWOW64\notepad.exe,0"</param> /// <param name="hive">eg The user-specific settings have priority over the computer settings. KeyHive.LocalMachine need admin rights</param> public static void CreateAssociation(string ProgID, string extension, string description, string application, string icon, KeyHiveSmall hive = KeyHiveSmall.CurrentUser) { RegistryKey selectedKey = null; switch (hive) { case KeyHiveSmall.ClassesRoot: Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(extension).SetValue("", ProgID); selectedKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(ProgID); break; case KeyHiveSmall.CurrentUser: Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + extension).SetValue("", ProgID); selectedKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + ProgID); break; case KeyHiveSmall.LocalMachine: Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\Classes\" + extension).SetValue("", ProgID); selectedKey = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\Classes\" + ProgID); break; } if (selectedKey != null) { if (description != null) { selectedKey.SetValue("", description); } if (icon != null) { selectedKey.CreateSubKey("DefaultIcon").SetValue("", icon, RegistryValueKind.ExpandString); selectedKey.CreateSubKey(@"Shell\Open").SetValue("icon", icon, RegistryValueKind.ExpandString); } if (application != null) { selectedKey.CreateSubKey(@"Shell\Open\command").SetValue("", "\"" + application + "\"" + " \"%1\"", RegistryValueKind.ExpandString); } } selectedKey.Flush(); selectedKey.Close(); } /// <summary> /// Creates a association for current running executable /// </summary> /// <param name="extension">eg .tmf</param> /// <param name="hive">eg KeyHive.LocalMachine need admin rights</param> /// <param name="description">eg Tool file. Displayed in explorer</param> public static void SelfCreateAssociation(string extension, KeyHiveSmall hive = KeyHiveSmall.CurrentUser, string description = "") { string ProgID = System.Reflection.Assembly.GetExecutingAssembly().EntryPoint.DeclaringType.FullName; string FileLocation = System.Reflection.Assembly.GetExecutingAssembly().Location; CreateAssociation(ProgID, extension, description, FileLocation, FileLocation + ",0", hive); } 
0
Oct. 24 '17 at 5:23
source share



All Articles