1; fileassoc.nsh
2; File association helper macros
3; Written by Saivert
4;
5; Features automatic backup system and UPDATEFILEASSOC macro for
6; shell change notification.
7;
8; |> How to use <|
9; To associate a file with an application so you can double-click it in explorer, use
10; the APP_ASSOCIATE macro like this:
11;
12;   Example:
13;   !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \
14;     "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\""
15;
16; Never insert the APP_ASSOCIATE macro multiple times, it is only ment
17; to associate an application with a single file and using the
18; the "open" verb as default. To add more verbs (actions) to a file
19; use the APP_ASSOCIATE_ADDVERB macro.
20;
21;   Example:
22;   !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \
23;     "$INSTDIR\myapp.exe /edit $\"%1$\""
24;
25; To have access to more options when registering the file association use the
26; APP_ASSOCIATE_EX macro. Here you can specify the verb and what verb is to be the
27; standard action (default verb).
28;
29; Note, that this script takes into account user versus global installs.
30; To properly work you must initialize the SHELL_CONTEXT variable via SetShellVarContext.
31;
32; And finally: To remove the association from the registry use the APP_UNASSOCIATE
33; macro. Here is another example just to wrap it up:
34;   !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile"
35;
36; |> Note <|
37; When defining your file class string always use the short form of your application title
38; then a period (dot) and the type of file. This keeps the file class sort of unique.
39;   Examples:
40;   Winamp.Playlist
41;   NSIS.Script
42;   Photoshop.JPEGFile
43;
44; |> Tech info <|
45; The registry key layout for a global file association is:
46;
47; HKEY_LOCAL_MACHINE\Software\Classes
48;     <".ext"> = <applicationID>
49;     <applicationID> = <"description">
50;         shell
51;             <verb> = <"menu-item text">
52;                 command = <"command string">
53;
54;
55; The registry key layout for a per-user file association is:
56;
57; HKEY_CURRENT_USER\Software\Classes
58;     <".ext"> = <applicationID>
59;     <applicationID> = <"description">
60;         shell
61;             <verb> = <"menu-item text">
62;                 command = <"command string">
63;
64
65!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
66  ; Backup the previously associated file class
67  ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" ""
68  WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
69
70  WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}"
71
72  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
73  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
74  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open"
75  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
76  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}`
77!macroend
78
79!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND
80  ; Backup the previously associated file class
81  ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" ""
82  WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
83
84  WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}"
85  StrCmp "${SHELLNEW}" "0" +2
86  WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}\ShellNew" "NullFile" ""
87
88  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
89  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
90  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" `${DEFAULTVERB}`
91  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
92  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
93!macroend
94
95!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND
96  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
97  WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
98!macroend
99
100!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB
101  DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}\shell\${VERB}`
102!macroend
103
104
105!macro APP_UNASSOCIATE EXT FILECLASS
106  ; Backup the previously associated file class
107  ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup`
108  WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0"
109
110  DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}`
111!macroend
112
113!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT
114  ReadRegStr ${OUTPUT} SHELL_CONTEXT "Software\Classes\.${EXT}" ""
115!macroend
116
117
118; !defines for use with SHChangeNotify
119!ifdef SHCNE_ASSOCCHANGED
120!undef SHCNE_ASSOCCHANGED
121!endif
122!define SHCNE_ASSOCCHANGED 0x08000000
123!ifdef SHCNF_FLUSH
124!undef SHCNF_FLUSH
125!endif
126!define SHCNF_FLUSH        0x1000
127
128!macro UPDATEFILEASSOC
129; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
130; can update the shell.
131  System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
132!macroend