Search code examples
wpfwindowsregistrynsisembedded-resource

Windows registry associate single application with multiple file types with unique icons


I am using NSIS to create an installer for an application I have developed using WPF which has about 3 different file formats it deals with and have been reading over the guidelines available from Microsoft extensively: https://msdn.microsoft.com/en-us/library/windows/desktop/cc144104

However I have found them lacking in examples for anything more complex and often when I try to find examples of how other applications are registering themselves (in the windows registry) it is not matching up with the previously mentioned guidelines at all...

But I have ended up with the following which seems to work fairly well, the application will start when associated files are opened through explorer and they are showing the default icon from the application executable:

# Register the application paths
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\GUI.exe" "" "$INSTDIR\GUI.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\GUI.exe" "Path" "$INSTDIR"

# Register the application
WriteRegStr HKCR "Applications\GUI.exe" "" "GUI"
WriteRegStr HKCR "Applications\GUI.exe" "DefaultIcon" "$INSTDIR\GUI.exe"
WriteRegStr HKCR "Applications\GUI.exe" "FriendlyAppName" "General User Interface"
WriteRegStr HKCR "Applications\GUI.exe" "UseExecutableForTaskbarGroupIcon" ""
WriteRegStr HKCR "Applications\GUI.exe\SupportedTypes" "" ""
WriteRegStr HKCR "Applications\GUI.exe\SupportedTypes\.ext1" "" ""
WriteRegStr HKCR "Applications\GUI.exe\SupportedTypes\.ext2" "" ""
WriteRegStr HKCR "Applications\GUI.exe\SupportedTypes\.ext3" "" ""

# Create the application ProgIDs
WriteRegStr HKCR "GUI.App" "" "GUI"
WriteRegStr HKCR "GUI.App" "DefaultIcon" "GUI.exe"
WriteRegStr HKCR "GUI.App\shell\open\command" "" 'GUI.exe "%1"'

# Associate application file extensions
WriteRegStr HKCR ".ext1" "" "GUI.App"
WriteRegStr HKCR ".ext1\OpenWithProgIds" "GUI.App" ""
WriteRegStr HKCR ".ext2" "" "GUI.App"
WriteRegStr HKCR ".ext2\OpenWithProgIds" "GUI.App" ""
WriteRegStr HKCR ".ext3" "" "GUI.App"
WriteRegBin HKCR ".ext3\OpenWithProgIds" "GUI.App" ""

# Calculate estimated EstimatedSize
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $INSTSIZE

# Write Add/Remove Programs Info
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GUI" "DisplayName" "General User Interface"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GUI" "UninstallString" "$INSTDIR\GUI.Uninstaller.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GUI" "DisplayIcon" "$INSTDIR\GUI.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GUI" "Publisher" "General User Interface Publisher"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GUI" "DisplayVersion" ${VERSION}
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GUI" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GUI" "NoRepair" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GUI" "EstimatedSize" $INSTSIZE

However I have noticed that the strings that I have specified as 'friendly' display values such as "GUI" and "General User Interface" are being ignored and it is instead using the assembly name from the executable, what could be causing this to happen?

The other problem is I want to be able to show a separate icon for each file extension I have associated with the application in explorer. So I have been looking into using Resource Hacker™ to insert additional icons and resources into my applications executable from the command line, but am actually entirely unsure of how to go about associating the non-default icons embedded in the executable with individual extensions and have been unable to find any resources or examples, so a push in the right direction would be greatly appreciated.

Lastly I am unsure of how to use the 'REG_EXPAND_SZ' registry data type to reference strings and other resources embedded in an executable, in some examples the resource names are prefixed with '-' and in others they are not... So any good learning resources on this would also be greatly appreciated.

Thanks, Alex.


Solution

  • Windows will read from the .exe if it cannot find your friendly name and it will also cache this name for future use (HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache and similar keys) so try to delete the cached name. Hopefully it will find your real friendly name if it has to go and look for it again.

    To get different icons for each type you also need one progid per type (myapp.type1, myapp.type2 etc.) so you can set different DefaultIcon paths for each type. The syntax of this path is c:\path\app.exe[,[-]number] where ...\app.exe,2 means the third (0,1,2) icon in app.exe and ...\app.exe,-2 means the icon with resource id 2. See this blog post for more details.

    Strings starting with @ are redirected strings and you can read about those on MSDN.

    Some final words of advice. Not everything in your example uses the full path, you should always specify the full path to your .exe.

    When all else fails, use Process Monitor to see what and where Windows is reading...