Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Associate File Extension with Application

I've written a program that edits a specific filetype , and I want to give the user the option to set my application as the default editor for this filetype (since I don't want an installer) on startup.

I've tried to write a re-useable method that associates a file for me (preferably on any OS, although I'm running Vista) by adding a key to HKEY_CLASSES_ROOT, and am using it with my application, but it doesn't seem to work.

public static void SetAssociation(string Extension, string KeyName, string OpenWith, string FileDescription) {     RegistryKey BaseKey;     RegistryKey OpenMethod;     RegistryKey Shell;     RegistryKey CurrentUser;      BaseKey = Registry.ClassesRoot.CreateSubKey(Extension);     BaseKey.SetValue("", KeyName);      OpenMethod = Registry.ClassesRoot.CreateSubKey(KeyName);     OpenMethod.SetValue("", FileDescription);     OpenMethod.CreateSubKey("DefaultIcon").SetValue("", "\"" + OpenWith + "\",0");     Shell = OpenMethod.CreateSubKey("Shell");     Shell.CreateSubKey("edit").CreateSubKey("command").SetValue("", "\"" + OpenWith + "\"" + " \"%1\"");     Shell.CreateSubKey("open").CreateSubKey("command").SetValue("", "\"" + OpenWith + "\"" + " \"%1\"");     BaseKey.Close();     OpenMethod.Close();     Shell.Close();      CurrentUser = Registry.CurrentUser.CreateSubKey(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" + Extension);     CurrentUser = CurrentUser.OpenSubKey("UserChoice", RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl);     CurrentUser.SetValue("Progid", KeyName, RegistryValueKind.String);     CurrentUser.Close(); } 

Any idea why it doesn't work? An example use might be

SetAssociation(".ucs", "UCS_Editor_File", Application.ExecutablePath, "UCS File");  

The part of the method that uses "CurrentUser" seems to work if I do the same using regedit, but using my application it doesn't.

like image 851
User2400 Avatar asked Apr 21 '10 09:04

User2400


People also ask

How do I associate an extension with an application?

Select General > Editors > File Associations. If the file extension does not appear in the File types list, click the Add button next to the File types list. Beside File type, enter the appropriate file extension, preceded by an asterisk. Click OK.

What does it mean to associate a file?

(1) The relationship of one file to another based on the data it contains. (2) An established relationship between a file and the application used to open it. There are default file associations pre-configured in every operating system for all the common file types.

How do I associate a file extension in Excel?

You can go to Control Panel > Default Programs > Associate a file type of protocol with a program. If it is already listed, you can change the default application to Excel. If it's not listed, you can add it.


1 Answers

The answer was a lot simpler than I expected. Windows Explorer has its own override for the open with application, and I was trying to modify it in the last lines of code. If you just delete the Explorer override, then the file association will work.

I also told explorer that I had changed a file association by calling the unmanaged function SHChangeNotify() using P/Invoke

public static void SetAssociation(string Extension, string KeyName, string OpenWith, string FileDescription) {     // The stuff that was above here is basically the same      // Delete the key instead of trying to change it     var CurrentUser = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + Extension, true);     CurrentUser.DeleteSubKey("UserChoice", false);     CurrentUser.Close();      // Tell explorer the file association has been changed     SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero); }  [DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); 
like image 50
User2400 Avatar answered Oct 11 '22 13:10

User2400