Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF application file association: DefaultIcon is not working

I want to association ".abc" file to my WPF application.

I add the association using this code:

public class FileAssociation
{
    static RegistryKey Root
    {
        get
        {
            return Registry.CurrentUser;
        }
    }

    // Associate file extension with progID, description, icon and application
    public static void Associate(string extension,
           string progID, string description, string application)
    {
        Require.NotNullOrEmpty(extension, "extension");
        Require.NotNullOrEmpty(progID, "progID");
        Require.NotNullOrEmpty(application, "application");
        Require.NotNullOrEmpty(description, "description");

        Root.CreateSubKey(extension).SetValue("", progID);

        using (var key = Root.CreateSubKey(progID))
        {
            key.SetValue("", description);

            key.CreateSubKey("DefaultIcon").SetValue("", ToShortPathName(application).Quote() + ",0");
            key.CreateSubKey(@"Shell\Open\Command").SetValue("", ToShortPathName(application).Quote() + " \"%1\"");

            // Tell explorer the file association has been changed
            SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
        }
    }

    // Return true if extension already associated in registry
    public static bool IsAssociated(string extension)
    {
        return (Root.OpenSubKey(extension, false) != null);
    }

    [DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);

    [DllImport("Kernel32.dll")]
    private static extern uint GetShortPathName(string lpszLongPath,
        [Out] StringBuilder lpszShortPath, uint cchBuffer);

    // Return short path format of a file name
    private static string ToShortPathName(string longName)
    {
        StringBuilder s = new StringBuilder(1000);
        uint iSize = (uint)s.Capacity;
        uint iRet = GetShortPathName(longName, s, iSize);
        return s.ToString();
    }
}

Note: The Quote() extension method is used just to make string abc to "abc".

Now the file association works fine! I can double click the ".abc" files to open my WPF app.

But the DefaultIcon is not working. The DefaultIcon Registery key is set to "D:\path\to\MyWPFApp.exe",0. The application icon of my WPF app is set to an icon in the properties page (I can see that the icon of MyWPFApp.exe is already changed). What's wrong? Thanks!

BTW: I'm using .NET 4 in Windows 8

like image 378
Mouhong Lin Avatar asked Nov 30 '25 09:11

Mouhong Lin


1 Answers

You don't need the DefaultIcon entry. The first icon is used by default.
remove it and it should work ^^

If I remove the ToShortPathName (long name is ok with quotes) and change the Root property returns Registry.ClassesRoot the code works here.

like image 142
kux Avatar answered Dec 01 '25 22:12

kux