1/*
2_____________________________________________________________________________
3
4                 Application Capabilities (Default Programs)
5_____________________________________________________________________________
6
7 By Joel Spadin
8 Loosely based on code taken from http://nsis.sourceforge.net/File_Association
9
10 These functions register an application with Windows Vista's and Windows 7's
11 Default Programs window.
12
13 Usage:
14
15 !include "Capabilities.nsh"
16 !define CAPABILITIES_NAME "[program name]"
17 !define CAPABILITIES_DESCRIPTION "[description]"
18 !define CAPABILITIES_PROGID "[progid]"
19 !define CAPABILITIES_PATH "[path]"
20 ...
21
22 During install, call ${RegisterCapabilities}, then use the other register
23 macros to create file type, MIME, and protocol associations.
24
25 During uninstall, call ${UnRegisterCapabilities}
26
27_______________________________________________________________________________
28
29 More information about Default Programs and Client Types can be found here:
30 http://msdn.microsoft.com/en-us/library/cc144154(VS.85).aspx
31 http://msdn.microsoft.com/en-us/library/cc144109(v=VS.85).aspx
32
33 Defines:  All defines not marked [optional] are required.
34
35 CAPABILITIES_NAME
36	The canonical name of the program.
37
38 CAPABILITIES_LOCAL_NAME 	[optional]
39	The localized name of the program as it appears in Default Programs.
40	This should be in the format "@FilePath,-StringID" where FilePath is the
41	path to a .dll or .exe file and StringID is the ID of a resource contained
42	in the file.
43
44 CAPABILITIES_DESCRIPTION
45	The localized description shown in Default Programs.  This can be either a
46	string or in the same format as CAPABILITIES_LOCAL_NAME
47
48 CAPABILITIES_PROGID
49	An identifier used in file associations.  Usually, this is the name of the
50	program.  This should not have any spaces in it.
51
52 CAPABILITIES_PATH
53	The location where capabilities info is stored in the registry.
54	The "Capabilities" key will automatically be added.  If the application is
55	a client of some sort, (browser, email, media player, etc.) use
56	"Software\Clients\[ClientType]\[ProgramName]".  Otherwise, use
57	"Software\[CompanyName]\[ProgramName]" or just "Software\[ProgramName]".
58
59 CAPABILITIES_ICON		[optional]
60	The icon shown in Default Programs.  This should be in the format
61	"FilePath,IconIndex" where FilePath is the path to a file containing the
62	icon.  If IconIndex is positive, the number is used as the index of the
63	zero-based array of icons stored in the file.  If IconIndex is negative,
64	the absolute value is used as a resource ID.
65
66 CAPABILITIES_REINSTALL		[optional]
67	The command executed when a user uses Set Program Access and Computer
68	Defaults to select this application as the default for its client type.
69	This command should launch a program that associates the application with
70	all the file and protocol types it can handle.
71
72 CAPABILITIES_HIDE_ICONS	[optional]
73	The command executed when a user uses Set Program Access and Computer
74	Defaults to disable access to this application.  This command should launch
75	a program that hides all shortcuts and access points to this application.
76	It should also prevent the application from being run automatically and
77	update the IconsVisible registry value to 0.
78
79 CAPABILITIES_SHOW_ICONS	[optional]
80	The command executed when a user uses Set Program Access and Computer
81	Defaults to enable access to this application.  This command should launch
82	a program that restores shortcuts and access points to the application,
83	allows the program to run, and updates the IconsVisible registry value to 1.
84
85
86Macros:
87
88 ${RegisterCapabilities}
89	Registers the program with Default Programs.  Call this once on install
90	before using any other functions.
91
92${UnRegisterCapabilities}
93	Un-registers the program and all its associations.  Call this once on
94	uninstall to clean up all installed registry values.
95
96${RegisterFileType} "[extension]" "[executable]" "[icon]" "[description]"
97	Registers a file type with the program
98	extension:		The file extension to register (ex: .txt)
99	executable:		The executable that opens the file type
100	icon:			The icon shown for the file type
101	description:	Description for the file type shown in Explorer
102
103${RegisterMediaType} "[extension]" "[executable]" "[icon]" "[description]"
104	Registers a media file type with the program (has a "Play" command)
105	(arguments are same as RegisterFileType)
106
107${RegisterMimeType} "[mime type]" "[shortname]" "[clsid]"
108	Registers a mime type with the program
109	mime type:		The MIME type to register (ex: audio/mp3)
110	shortname:		A short identifier for the type (ex: mp3)
111	clsid:			The CLSID of the program to handle files of this type
112
113${RegisterProtocol}	"[protocol]" "[executable]" "[icon]" "[description]"
114	Registers a URL protocol with the program
115	protocol:		The protocol to register (ex: http)
116	(other arguments are same as RegisterFileType)
117
118${UnRegisterFileType} "[extension]"
119	Un-registers a previously registered file type
120	extension:		The file extension to un-register
121
122${UnRegisterMimeType} "[mime type]"
123	Un-registers a previously registered MEME type
124	mime type:		The MIME type to un-register
125
126${UnRegisterProtocol} "[protocol]"
127	Un-registers a previously registered URL protocol
128	protocol:		The URL protocol to un-register
129
130*/
131
132
133
134
135!ifndef Capabilities_INCLUDED
136!define Capabilities_INCLUDED
137
138!include "Util.nsh"
139!include "StrFunc.nsh"
140
141${StrCase}
142
143!verbose push
144!verbose 3
145!ifndef _Capabilities_VERBOSE
146	!define _Capabilities_VERBOSE 3
147!endif
148!verbose ${_Capabilities_VERBOSE}
149!define Capabilities_VERBOSE `!insertmacro Capabilities_VERBOSE`
150!verbose pop
151
152!macro Capabilities_VERBOSE _VERBOSE
153	!verbose push
154	!verbose 3
155	!undef _Capabilities_VERBOSE
156	!define _Capabilities_VERBOSE ${_VERBOSE}
157	!verbose pop
158!macroend
159
160!macro RegisterCapabilitiesCall
161	!verbose push
162	!verbose ${_Capabilities_VERBOSE}
163	${CallArtificialFunction} RegisterCapabilities_
164	!verbose pop
165!macroend
166
167!macro UnRegisterCapabilitiesCall
168	!verbose push
169	!verbose ${_Capabilities_VERBOSE}
170	${CallArtificialFunction} UnRegisterCapabilities_
171	!verbose pop
172!macroend
173
174!macro RegisterFileTypeCall _EXTENSION _EXECUTABLE _ICON _DESCRIPTION
175	!verbose push
176	!verbose ${_Capabilities_VERBOSE}
177	Push `${_DESCRIPTION}`
178	Push `${_ICON}`
179	Push `${_EXECUTABLE}`
180	Push `${_EXTENSION}`
181	${CallArtificialFunction} RegisterFileType_
182	!verbose pop
183!macroend
184
185!macro RegisterMediaTypeCall _EXTENSION _EXECUTABLE _ICON _DESCRIPTION
186	!verbose push
187	!verbose ${_Capabilities_VERBOSE}
188	Push `${_DESCRIPTION}`
189	Push `${_ICON}`
190	Push `${_EXECUTABLE}`
191	Push `${_EXTENSION}`
192	${CallArtificialFunction} RegisterMediaType_
193	!verbose pop
194!macroend
195
196!macro RegisterMimeTypeCall _MIMETYPE _SHORTNAME _CLSID
197	!verbose push
198	!verbose ${_Capabilities_VERBOSE}
199	Push `${_CLSID}`
200	Push `${_SHORTNAME}`
201	Push `${_MIMETYPE}`
202	${CallArtificialFunction} RegisterMimeType_
203	!verbose pop
204!macroend
205
206!macro RegisterProtocolCall _PROTOCOL _EXECUTABLE _ICON _DESCRIPTION
207	!verbose push
208	!verbose ${_Capabilities_VERBOSE}
209	Push `${_DESCRIPTION}`
210	Push `${_ICON}`
211	Push `${_EXECUTABLE}`
212	Push `${_PROTOCOL}`
213	${CallArtificialFunction} RegisterProtocol_
214	!verbose pop
215!macroend
216
217!macro UnRegisterFileTypeCall _EXTENSION
218	!verbose push
219	!verbose ${_Capabilities_VERBOSE}
220	Push `${_EXTENSION}`
221	${CallArtificialFunction} UnRegisterFileType_
222	!verbose pop
223!macroend
224
225!macro UnRegisterMimeTypeCall _MIMETYPE
226	!verbose push
227	!verbose ${_Capabilities_VERBOSE}
228	Push `${_MIMETYPE}`
229	${CallArtificialFunction} UnRegisterMimeType_
230	!verbose pop
231!macroend
232
233!macro UnRegisterProtocolCall _PROTOCOL
234	!verbose push
235	!verbose ${_Capabilities_VERBOSE}
236	Push `${_MIMETYPE}`
237	${CallArtificialFunction} UnRegisterProtocol_
238	!verbose pop
239!macroend
240
241
242
243
244!define RegisterCapabilities `!insertmacro RegisterCapabilitiesCall`
245!define un.RegisterCapabilities `!insertmacro RegisterCapabilitiesCall`
246
247!macro RegisterCapabilities
248!macroend
249
250!macro un.RegisterCapabilities
251!macroend
252
253!macro RegisterCapabilities_
254	!verbose push
255	!verbose ${_Capabilities_VERBOSE}
256	Push $0
257
258	!ifndef CAPABILITIES_PATH
259		!error "CAPABILITIES_PATH not defined"
260	!endif
261	!ifndef CAPABILITIES_NAME
262		!error "CAPABILITIES_NAME not defined"
263	!endif
264	!ifndef CAPABILITIES_PROGID
265		!error "CAPABILITIES_PROGID not defined"
266	!endif
267	!ifndef CAPABILITIES_DESCRIPTION
268		!error "CAPABILITIES_DESCRIPTION not defined"
269	!endif
270
271	StrCpy $0 "${CAPABILITIES_PATH}\Capabilities"
272	; add the application to RegisteredApplications
273	WriteRegStr HKLM "Software\RegisteredApplications" "${CAPABILITIES_NAME}" "$0"
274
275	; write application info
276	WriteRegStr HKLM "${CAPABILITIES_PATH}" "" "${CAPABILITIES_NAME}"
277
278	!ifdef CAPABILITIES_LOCAL_NAME
279		WriteRegStr HKLM "${CAPABILITIES_PATH}" "LocalizedString" "${CAPABILITIES_LOCAL_NAME}"
280	!endif
281	!ifdef CAPABILITIES_ICON
282		WriteRegStr HKLM "${CAPABILITIES_PATH}\DefaultIcon" "" "${CAPABILITIES_ICON}"
283	!endif
284
285	; write installinfo if defined
286	!ifdef CAPABILITIES_REINSTALL
287		WriteRegStr HKLM "${CAPABILITIES_PATH}\InstallInfo" "ReinstallCommand" "${CAPABILITIES_REINSTALL}"
288	!endif
289	!ifdef CAPABILITIES_HIDE_ICONS
290		WriteRegStr HKLM "${CAPABILITIES_PATH}\InstallInfo" "HideIconsCommand" "${CAPABILITIES_HIDE_ICONS}"
291		WriteRegDWORD HKLM "${CAPABILITIES_PATH}\InstallInfo" "IconsVisible" 0x1
292	!endif
293	!ifdef CAPABILITIES_SHOW_ICONS
294		WriteRegStr HKLM "${CAPABILITIES_PATH}\InstallInfo" "ShowIconsCommand" "${CAPABILITIES_SHOW_ICONS}"
295		WriteRegDWORD HKLM "${CAPABILITIES_PATH}\InstallInfo" "IconsVisible" 0x1
296	!endif
297
298	; write application capabilities info
299	!ifdef CAPABILITIES_LOCAL_NAME
300		WriteRegStr HKLM "$0" "ApplicationName" "${CAPABILITIES_LOCAL_NAME}"
301	!else
302		WriteRegStr HKLM "$0" "ApplicationName" "${CAPABILITIES_NAME}"
303	!endif
304	WriteRegStr HKLM "$0" "ApplicationDescription" "${CAPABILITIES_DESCRIPTION}"
305
306	Pop $0
307	!verbose pop
308!macroend
309
310
311
312!define UnRegisterCapabilities `!insertmacro UnRegisterCapabilitiesCall`
313!define un.UnRegisterCapabilities `!insertmacro UnRegisterCapabilitiesCall`
314
315!macro UnRegisterCapabilities
316!macroend
317
318!macro un.UnRegisterCapabilities
319!macroend
320
321!macro UnRegisterCapabilities_
322	!define MacroID ${__LINE__}
323	!verbose push
324	!verbose ${_Capabilities_VERBOSE}
325
326	Push $0
327	Push $1
328
329	; remove all file associations
330	FileTypeLoop_${MacroID}:
331		EnumRegValue $0 HKLM "${CAPABILITIES_PATH}\Capabilities\FileAssociations" 0
332		StrCmp $0 "" FileTypeDone_${MacroID}
333
334		ReadRegStr $1 HKLM "${CAPABILITIES_PATH}\Capabilities\FileAssociations" "$0"
335		DeleteRegKey HKCR $1
336		DeleteRegValue HKLM "${CAPABILITIES_PATH}\Capabilities\FileAssociations" "$0"
337
338		Goto FileTypeLoop_${MacroID}
339	FileTypeDone_${MacroID}:
340
341	; remove all MIME associations
342	MimeTypeLoop_${MacroID}:
343		EnumRegValue $0 HKLM "${CAPABILITIES_PATH}\Capabilities\MimeAssociations" 0
344		StrCmp $0 "" MimeTypeDone_${MacroID}
345
346		ReadRegStr $1 HKLM "${CAPABILITIES_PATH}\Capabilities\MimeAssociations" "$0"
347		DeleteRegKey HKCR "$1"
348		DeleteRegValue HKLM "${CAPABILITIES_PATH}\Capabilities\MimeAssociations" "$0"
349
350		Goto MimeTypeLoop_${MacroID}
351	MimeTypeDone_${MacroID}:
352
353	; remove all protocol associations
354	ProtocolLoop_${MacroID}:
355		EnumRegValue $0 HKLM "${CAPABILITIES_PATH}\Capabilities\UrlAssociations" 0
356		StrCmp $0 "" ProtocolDone_${MacroID}
357
358		ReadRegStr $1 HKLM "${CAPABILITIES_PATH}\Capabilities\UrlAssociations" "$0"
359		DeleteRegKey HKCR "$1"
360		DeleteRegValue HKLM "${CAPABILITIES_PATH}\Capabilities\UrlAssociations" "$0"
361
362		Goto ProtocolLoop_${MacroID}
363	ProtocolDone_${MacroID}:
364
365
366	; remove capabilities keys
367	DeleteRegValue HKLM "Software\RegisteredApplications" "${CAPABILITIES_NAME}"
368	DeleteRegKey HKLM ${CAPABILITIES_PATH}
369
370	Pop $1
371	Pop $0
372	!verbose pop
373	!undef MacroID
374!macroend
375
376
377
378
379
380!define RegisterFileType `!insertmacro RegisterFileTypeCall`
381!define un.RegisterFileType `!insertmacro RegisterFileTypeCall`
382
383!macro RegisterFileType
384!macroend
385
386!macro un.RegisterFileType
387!macroend
388
389
390!macro RegisterFileType_
391	!verbose push
392	!verbose ${_Capabilities_VERBOSE}
393
394	Exch $R3 ;ext
395	Exch
396	Exch $R2 ;exe
397	Exch 2
398	Exch $R1 ;icon
399	Exch
400	Exch 3
401	Exch $R0 ;desc
402	Push $0
403
404	; create an association name
405	; ex: .mp3 becomes ProgID.AssocFile.MP3
406	${StrCase} $0 "$R3" "U"
407	StrCpy $0 "${CAPABILITIES_PROGID}.AssocFile$0"
408
409	; link capabilities to association in classes root
410	WriteRegStr HKLM "${CAPABILITIES_PATH}\Capabilities\FileAssociations" "$R3" "$0"
411
412	; write file association in classes root
413	WriteRegStr HKCR "$0" "" "$R0"
414	WriteRegStr HKCR "$0\DefaultIcon" "" "$R1"
415	WriteRegStr HKCR "$0\shell" "" "Open"
416	WriteRegStr HKCR "$0\shell\open" "" "&Open"
417	WriteRegStr HKCR "$0\shell\open\command" "" '"$R2" "%1"'
418
419	Pop $0
420	Pop $R0
421	Pop $R1
422	Pop $R2
423	Pop $R3
424
425	!verbose pop
426!macroend
427
428
429
430
431!define RegisterMediaType `!insertmacro RegisterMediaTypeCall`
432!define un.RegisterMediaType `!insertmacro RegisterMediaTypeCall`
433
434!macro RegisterMediaType
435!macroend
436
437!macro un.RegisterMediaType
438!macroend
439
440
441!macro RegisterMediaType_
442	!verbose push
443	!verbose ${_Capabilities_VERBOSE}
444
445	Exch $R3 ;ext
446	Exch
447	Exch $R2 ;exe
448	Exch 2
449	Exch $R1 ;icon
450	Exch
451	Exch 3
452	Exch $R0 ;desc
453	Push $0
454
455
456	; create an association name
457	; ex: .mp3 becomes ProgID.AssocFile.MP3
458	${StrCase} $0 "$R3" "U"
459	StrCpy $0 "${CAPABILITIES_PROGID}.AssocFile$0"
460
461	; link capabilities to association in classes root
462	WriteRegStr HKLM "${CAPABILITIES_PATH}\Capabilities\FileAssociations" "$R3" "$0"
463
464	; write file association in classes root
465	WriteRegStr HKCR "$0" "" "$R0"
466	WriteRegStr HKCR "$0\DefaultIcon" "" "$R1"
467	WriteRegStr HKCR "$0\shell" "" "Play"
468	WriteRegStr HKCR "$0\shell\open" "" "&Open"
469	WriteRegStr HKCR "$0\shell\open\command" "" '"$R2" "%1"'
470	WriteRegStr HKCR "$0\shell\play" "" "&Play"
471	WriteRegStr HKCR "$0\shell\play\command" "" '"$R2" "%L"'
472
473	Pop $0
474	Pop $R0
475	Pop $R1
476	Pop $R2
477	Pop $R3
478
479	!verbose pop
480!macroend
481
482
483
484
485!define RegisterMimeType `!insertmacro RegisterMimeTypeCall`
486!define un.RegisterMimeType `!insertmacro RegisterMimeTypeCall`
487
488!macro RegisterMimeType
489!macroend
490
491!macro un.RegisterMimeType
492!macroend
493
494
495!macro RegisterMimeType_
496	!verbose push
497	!verbose ${_Capabilities_VERBOSE}
498
499	Exch $R2 ;mime
500	Exch
501	Exch $R1 ;shortname
502	Exch
503	Exch 2
504	Exch $R0 ;clsid
505
506	Push $0
507
508	; create an association name
509	; ex: audio/mp3 becomes ProgID.AssocMIME.MP3
510	${StrCase} $0 "$R1" "U"
511	StrCpy $0 "${CAPABILITIES_PROGID}.AssocMIME.$0"
512
513	; link capabilities to association in classes root
514	WriteRegStr HKLM "${CAPABILITIES_PATH}\Capabilities\MimeAssociations" "$R2" "$0"
515
516	; write file association in classes root
517	WriteRegStr HKCR "$0\CLSID" "" "$R0"
518
519	Pop $0
520	Pop $R0
521	Pop $R1
522
523	!verbose pop
524!macroend
525
526
527
528!define RegisterProtocol `!insertmacro RegisterProtocolCall`
529!define un.RegisterProtocol `!insertmacro RegisterProtocolCall`
530
531!macro RegisterProtocol
532!macroend
533
534!macro un.RegisterProtocol
535!macroend
536
537
538!macro RegisterProtocol_
539	!verbose push
540	!verbose ${_Capabilities_VERBOSE}
541
542	Exch $R3 ;protocol
543	Exch
544	Exch $R2 ;exe
545	Exch 2
546	Exch $R1 ;icon
547	Exch
548	Exch 3
549	Exch $R0 ;desc
550	Push $0
551
552
553	; create an association name
554	; ex: http becomes ProgID.AssocProtocol.HTTP
555	${StrCase} $0 "$R3" "U"
556	StrCpy $0 "${CAPABILITIES_PROGID}.AssocProtocol.$0"
557
558	; link capabilities to association in classes root
559	WriteRegStr HKLM "${CAPABILITIES_PATH}\Capabilities\UrlAssociations" "$R3" "$0"
560
561	; write file association in classes root
562	WriteRegStr HKCR "$0" "" "$R0"
563	WriteRegStr HKCR "$0\DefaultIcon" "" "$R1"
564	WriteRegStr HKCR "$0\shell\open" "" "&Open"
565	WriteRegStr HKCR "$0\shell\open\command" "" '"$R2" "%1"'
566
567	Pop $0
568	Pop $R0
569	Pop $R1
570	Pop $R2
571	Pop $R3
572
573	!verbose pop
574!macroend
575
576
577
578
579!define UnRegisterFileType `!insertmacro UnRegisterFileTypeCall`
580!define un.UnRegisterFileType `!insertmacro UnRegisterFileTypeCall`
581
582!macro UnRegisterFileType
583!macroend
584
585!macro un.UnRegisterFileType
586!macroend
587
588!macro UnRegisterFileType_
589	!define MacroID ${__LINE__}
590	!verbose push
591	!verbose ${_Capabilities_VERBOSE}
592
593	Exch $R0 ;ext
594	Push $0
595
596	ReadRegStr $0 HKLM "${CAPABILITIES_PATH}\Capabilities\FileAssociations" "$R0"
597	StrCmp $0 "" skip_${MacroID}
598
599	DeleteRegKey HKCR "$0"
600	DeleteRegValue HKLM "${CAPABILITIES_PATH}\Capabilities\FileAssociations" "$R0"
601	skip_${MacroID}:
602
603	Pop $0
604	Pop $R0
605	!verbose pop
606	!undef MacroID
607!macroend
608
609
610
611!define UnRegisterMimeType `!insertmacro UnRegisterMimeTypeCall`
612!define un.UnRegisterMimeType `!insertmacro UnRegisterMimeTypeCall`
613
614!macro UnRegisterMimeType
615!macroend
616
617!macro un.UnRegisterMimeType
618!macroend
619
620!macro UnRegisterMimeType_
621	!define MacroID ${__LINE__}
622	!verbose push
623	!verbose ${_Capabilities_VERBOSE}
624
625	Exch $R0 ;mime
626	Push $0
627
628	ReadRegStr $0 HKLM "${CAPABILITIES_PATH}\Capabilities\MimeAssociations" "$R0"
629	StrCmp $0 "" skip_${MacroID}
630
631	DeleteRegKey HKCR "$0"
632	DeleteRegValue HKLM "${CAPABILITIES_PATH}\Capabilities\MimeAssociations" "$R0"
633	skip_${MacroID}:
634
635	Pop $0
636	Pop $R0
637	!verbose pop
638	!undef MacroID
639!macroend
640
641
642
643!define UnRegisterProtocol `!insertmacro UnRegisterProtocolCall`
644!define un.UnRegisterProtocol `!insertmacro UnRegisterProtocolCall`
645
646!macro UnRegisterProtocol
647!macroend
648
649!macro un.UnRegisterProtocol
650!macroend
651
652!macro UnRegisterProtocol_
653	!define MacroID ${__LINE__}
654	!verbose push
655	!verbose ${_Capabilities_VERBOSE}
656
657	Exch $R0 ;protocol
658	Push $0
659
660	ReadRegStr $0 HKLM "${CAPABILITIES_PATH}\Capabilities\UrlAssociations" "$R0"
661	StrCmp $0 "" skip_${MacroID}
662
663	DeleteRegKey HKCR "$0"
664	DeleteRegValue HKLM "${CAPABILITIES_PATH}\Capabilities\UrlAssociations" "$R0"
665	skip_${MacroID}:
666
667	Pop $0
668	Pop $R0
669	!verbose pop
670	!undef MacroID
671!macroend
672
673
674
675
676!endif