Warning, /network/falkon/windows/AllAssociation.nsh is written in an unsupported language. File is not indexed.

0001 /*
0002 _____________________________________________________________________________
0003 
0004                        All Association
0005 _____________________________________________________________________________
0006 
0007 
0008 
0009  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
0010  ; Date: 2012-Nov-18, S. Razi Alavizadeh, v0.1                            ;
0011  ; Some Codes are based on code taken from:                               ;
0012  ; http://nsis.sourceforge.net/File_Association                           ;
0013  ; Ability to register protocol and extension associations.               ;
0014  ; It supports old association method and new method by using             ;
0015  ; IApplicationAssociationRegistration APIs.                              ;
0016  ; that needed 'AppAssocReg' plugins, downloadable from:                  ;
0017  ; http://nsis.sourceforge.net/SetVistaDefaultApp_plug-in                 ;
0018  ; and also add support for set as default backuped association when      ;
0019  ; uninstalling. This needed 'Registery' plugins.                         ;
0020  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
0021 
0022  Requirment:
0023  1. 'AppAssocReg' plugins.
0024  2. 'Registery' plugins.
0025 
0026  Usage in script:
0027  1. !include "AllAssociation.nsh"
0028  2. [Section|Function]
0029       ${AllAssociationFunction} "Param1" "Param2" "..." $var
0030     [SectionEnd|FunctionEnd]
0031 
0032  AllAssociationFunction=[RegisterAssociation|UnRegisterAssociation|CreateProgId|UpdateSystemIcons|SetAsDefaultNoAppName]
0033 
0034 _____________________________________________________________________________
0035 
0036  ${RegisterAssociation} "[assoc_name]" "[executable]" "[prog_id]" "[description]" "[icon]" "[type]"
0037 
0038 "[assoc_name]"     ; assoc_name, which is file format's extension if type is "file" and is protocol's name if type is "protocol".
0039                    ;
0040 "[executable]"     ; executable which opens the file format or is protocol handler.
0041                    ;
0042 "[prog_id]"        ; registery internal id for assoc_name, on Vista+ if type is "protocol" this is our registered ProgId for assoc_name and is used for comparison.
0043                    ;
0044 "[description]"    ; description for the assoc_name. This will be display in Windows Explorer.
0045                    ;
0046 "[icon]"           ; icon path for this association.
0047                    ;
0048 "[type]"           ; type of association. "file" for extension and "protocol" for protocol handler.
0049                    ;
0050 
0051  ${UnRegisterAssociation} "[assoc_name]" "[prog_id]" "[executable]" "[type]"
0052 
0053 "[assoc_name]"     ; assoc_name, which is file format's extension if type is "file" and is protocol's name if type is "protocol".
0054                    ;
0055 "[prog_id]"        ; registery internal id for assoc_name
0056                    ;
0057 "[executable]"     ; executable which opens the file format or is protocol handler.
0058                    ;
0059 "[type]"           ; type of association. "file" for extension and "protocol" for protocol handler.
0060                    ;
0061 
0062  ${CreateProgId} "[prog_id]" "[executable]" "[description]" "[icon]"
0063 
0064 "[prog_id]"        ; registery internal id for assoc_name
0065                    ;
0066 "[executable]"     ; executable which opens the file format or is protocol handler.
0067                    ;
0068 "[description]"    ; description for the assoc_name. This will be display in Windows Explorer.
0069                    ;
0070 "[icon]"           ; icon path for this prog_id.
0071                    ;
0072 
0073 
0074  ${SetAsDefaultNoAppName} "[prog_id]" "[assoc_name]" "[type]"
0075 
0076 "[prog_id]"        ; registery internal id for assoc_name
0077                    ;
0078 "[assoc_name]"     ; assoc_name, which is file format's extension if type is "file" and is protocol's name if type is "protocol".
0079                    ;
0080 "[type]"           ; type of association. "file" for extension and "protocol" for protocol handler.
0081                    ;
0082 
0083  ${UpdateSystemIcons} ; it has not arguments and just notifies OS for updating icons for new associations.
0084 
0085 _____________________________________________________________________________
0086 
0087                          Macros
0088 _____________________________________________________________________________
0089 
0090  Change log window verbosity (default: 3=no script)
0091 
0092  Example:
0093  !include "AllAssociation.nsh"
0094  !insertmacro RegisterAssociation
0095  ${AllAssociation_VERBOSE} 4   # all verbosity
0096  !insertmacro UnRegisterAssociation
0097  ${AllAssociation_VERBOSE} 3   # no script
0098 */
0099 
0100 
0101 !ifndef AllAssociation_INCLUDED
0102 !define AllAssociation_INCLUDED
0103 
0104 !include Util.nsh
0105 
0106 !verbose push
0107 !verbose 3
0108 !ifndef _AllAssociation_VERBOSE
0109   !define _AllAssociation_VERBOSE 3
0110 !endif
0111 !verbose ${_AllAssociation_VERBOSE}
0112 !define AllAssociation_VERBOSE `!insertmacro AllAssociation_VERBOSE`
0113 !verbose pop
0114 
0115 !macro AllAssociation_VERBOSE _VERBOSE
0116   !verbose push
0117   !verbose 3
0118   !undef _AllAssociation_VERBOSE
0119   !define _AllAssociation_VERBOSE ${_VERBOSE}
0120   !verbose pop
0121 !macroend
0122 
0123 
0124 ; define some registery macros
0125 !define RegistryRead `!insertmacro RegistryRead`
0126 
0127 !macro RegistryRead _PATH _VALUE _STRING _TYPE
0128         registry::_Read /NOUNLOAD `${_PATH}` `${_VALUE}`
0129         Pop ${_STRING}
0130         Pop ${_TYPE}
0131 !macroend
0132 
0133 
0134 !define RegistryWrite `!insertmacro RegistryWrite`
0135 
0136 !macro RegistryWrite _PATH _VALUE _STRING _TYPE _ERR
0137         registry::_Write /NOUNLOAD `${_PATH}` `${_VALUE}` `${_STRING}` `${_TYPE}`
0138         Pop ${_ERR}
0139 !macroend
0140 
0141 !define RegistryFind `!insertmacro RegistryFind`
0142 
0143 !macro RegistryFind _HANDLE _PATH _VALUEORKEY _STRING _TYPE
0144         registry::_Find /NOUNLOAD `${_HANDLE}`
0145         Pop ${_PATH}
0146         Pop ${_VALUEORKEY}
0147         Pop ${_STRING}
0148         Pop ${_TYPE}
0149 !macroend
0150 
0151 !define RegistryOpen `!insertmacro RegistryOpen`
0152 
0153 !macro RegistryOpen _PATH _OPTIONS _HANDLE
0154         registry::_Open /NOUNLOAD `${_PATH}` `${_OPTIONS}`
0155         Pop ${_HANDLE}
0156 !macroend
0157 
0158 !macro RegisterAssociationCall _EXTENSION _EXECUTABLE _PROG_ID _DESCRIPTION _ICON _TYPE
0159   !verbose push
0160   !verbose ${_AllAssociation_VERBOSE}
0161 
0162   Push `${_EXECUTABLE}`
0163   Push `${_PROG_ID}`
0164   Push `${_DESCRIPTION}`
0165   Push `${_ICON}`
0166 
0167   ${CallArtificialFunction} CreateProgId_
0168 
0169 
0170   Push `${_PROG_ID}`
0171   Push `${_EXECUTABLE}`
0172   Push `${_EXTENSION}`
0173   Push `${_TYPE}`
0174 
0175   ${CallArtificialFunction} RegisterAssociation_
0176 
0177   !verbose pop
0178 !macroend
0179 
0180 !macro UnRegisterAssociationCall _EXTENSION _PROG_ID _EXECUTABLE _TYPE
0181   !verbose push
0182   !verbose ${_AllAssociation_VERBOSE}
0183   Push `${_EXTENSION}`
0184   Push `${_EXECUTABLE}`
0185   Push `${_PROG_ID}`
0186   Push `${_TYPE}`
0187 
0188   ${CallArtificialFunction} UnRegisterAssociation_
0189 
0190   ; backuped ProgId was pushed from UnRegisterAssociation_
0191   Push `${_EXTENSION}`
0192   Push `${_TYPE}` ; type of association
0193   ${CallArtificialFunction} SetAsDefaultNoAppName_
0194 
0195   !verbose pop
0196 !macroend
0197 
0198 !macro CreateProgIdCall _PROG_ID _EXECUTABLE _DESCRIPTION _ICON
0199   !verbose push
0200   !verbose ${_AllAssociation_VERBOSE}
0201   Push `${_EXECUTABLE}`
0202   Push `${_PROG_ID}`
0203   Push `${_DESCRIPTION}`
0204   Push `${_ICON}`
0205 
0206   ${CallArtificialFunction} CreateProgId_
0207   !verbose pop
0208 !macroend
0209 
0210 !macro SetAsDefaultNoAppNameCall _PROG_ID _EXTENSION _TYPE
0211   !verbose push
0212   !verbose ${_AllAssociation_VERBOSE}
0213   Push `${_PROG_ID}`
0214   Push `${_EXTENSION}`
0215   Push `${_TYPE}`
0216 
0217   ${CallArtificialFunction} SetAsDefaultNoAppName_
0218   !verbose pop
0219 !macroend
0220 
0221 !define SetAsDefaultNoAppName `!insertmacro SetAsDefaultNoAppNameCall`
0222 !define un.SetAsDefaultNoAppName `!insertmacro SetAsDefaultNoAppNameCall`
0223 
0224 !macro SetAsDefaultNoAppName
0225 !macroend
0226 
0227 !macro un.SetAsDefaultNoAppName
0228 !macroend
0229 
0230 !macro SetAsDefaultNoAppName_
0231   !verbose push
0232   !verbose ${_AllAssociation_VERBOSE}
0233 
0234   Pop $R0 ; TYPE
0235   Pop $R1 ; EXTENSION
0236   Pop $R2 ; PROG_ID
0237 
0238   StrCmp $R2 "No ProgId Pushed" NoBackupedProgId 0
0239   StrCmp $R2 "" NoBackupedProgId 0
0240   StrCmp $R1 "" NoBackupedProgId 0
0241     ${RegistryOpen} "HKLM\SOFTWARE\RegisteredApplications" "/K=0 /V=1 /S=0 /B=1" $R8 ; R8 = first registery handle
0242         StrCmp $R8 0 close 0
0243 loop1:
0244         ${RegistryFind} "$R8" $1 $R3 $3 $4 ; $R3 = AppRegisteredName
0245         StrCmp $1 "" close 0
0246 
0247         ${RegistryOpen} "HKLM\$3" "/K=0 /V=1 /S=0 /B=1 /N='$R1'" $R9 ; R9 = second registery handle
0248         StrCmp $R9 0 loop1 0
0249 loop2:
0250         ${RegistryFind} "$R9" $1 $2 $R4 $4 ; $R4 = ProgId registered for EXTENSION
0251         StrCmp $1 "" loop1 0
0252         StrCmp $R4 "$R2" 0 loop2
0253 
0254         AppAssocReg::SetAppAsDefault "$R3" "$R1" "$R0"
0255 
0256 close:
0257         registry::_Close /NOUNLOAD "$R9"
0258         registry::_Close /NOUNLOAD "$R8"
0259         registry::_Unload
0260 
0261 NoBackupedProgId:
0262   !verbose pop
0263 !macroend
0264 
0265 !define CreateProgId `!insertmacro CreateProgIdCall`
0266 !define un.CreateProgId `!insertmacro CreateProgIdCall`
0267 
0268 !macro CreateProgId
0269 !macroend
0270 
0271 !macro un.CreateProgId
0272 !macroend
0273 
0274 !macro CreateProgId_
0275   !verbose push
0276   !verbose ${_AllAssociation_VERBOSE}
0277 
0278   Pop $R0 ;ICON
0279   Pop $R1 ;DESCRIPTION
0280   Pop $R2 ;PROG_ID
0281   Pop $R3 ;EXECUTABLE
0282 
0283   ReadRegStr $0 HKCR $R2 ""
0284 ;  StrCmp $0 "" 0 JustSkip ; if icon and description are present then just skip
0285     WriteRegStr HKCR "$R2" "" "$R1"
0286     WriteRegStr HKCR "$R2\shell" "" "open"
0287     WriteRegStr HKCR "$R2\DefaultIcon" "" "$R0"
0288 ;JustSkip:
0289   WriteRegStr HKCR "$R2\shell\open\command" "" '"$R3" "%1"'
0290   WriteRegStr HKCR "$R2\shell\edit" "" "Edit $R1"
0291   WriteRegStr HKCR "$R2\shell\edit\command" "" '"$R3" "%1"'
0292 
0293   !verbose pop
0294 !macroend
0295 
0296 !define RegisterAssociation `!insertmacro RegisterAssociationCall`
0297 !define un.RegisterAssociation `!insertmacro RegisterAssociationCall`
0298 
0299 !macro RegisterAssociation
0300 !macroend
0301 
0302 !macro un.RegisterAssociation
0303 !macroend
0304 
0305 !macro RegisterAssociation_
0306   !verbose push
0307   !verbose ${_AllAssociation_VERBOSE}
0308 
0309   Pop $R0 ;type = file or protocol
0310   Pop $R1 ;association name = ext or protocol
0311   Pop $R2 ;exe
0312   Pop $R3 ;prog_id
0313 
0314 
0315   StrCmp "$R0" "file" 0 NoFile
0316 ; file
0317     ReadRegStr $1 HKCR $R1 ""  ; read current file association
0318     StrCmp "$1" "" NoFileExtBackup  ; is it empty
0319     StrCmp "$1" "$R3" NoFileExtBackup  ; it is our own
0320       WriteRegStr HKCR $R1 "backup_val" "$1"  ; backup current value
0321 NoFileExtBackup:
0322     WriteRegStr HKCR $R1 "" "$R3"  ; set our file association
0323 Goto VistaPlus
0324 
0325 NoFile:
0326 ; Protocol
0327   StrCmp "$R0" "protocol" 0 NotSupported
0328     ; write protocol flag
0329     WriteRegStr HKCR $R1 "URL Protocol" ""
0330         ;get prog_id of current default
0331 
0332         AppAssocReg::QueryCurrentDefault $R1 "protocol" "user"
0333     Pop $1
0334         StrCmp "$1" "method failed" NoProgID 0
0335         StrCmp "$1" "method not available" NoProgID 0
0336     StrCmp "$1" "$R3" NoProgID 0   ; it is our own
0337       WriteRegStr HKCR "$R1\shell\open\command" "backup_progid" "$1"  ; backup current progid
0338 NoProgID:
0339 ;    ReadRegStr $1 HKCR "$R1\shell\open\command" ""  ; read current protocol association
0340         ; some applications write this as REG_EXPAND_SZ and don't work with REG_SZ (e.g.: some version of Opera)
0341         ${RegistryRead} "HKCR\$R1\shell\open\command" "" '$1' '$0' ; read current protocol association and its registery type
0342     StrCmp "$1" "" NoProtocolBackup  ; is it empty
0343     StrCmp "$1" '"$R2" "%1"'  NoProtocolBackup  ; it is our own
0344       ;WriteRegStr HKCR "$R1\shell\open\command" "backup_val" "$1"  ; backup current value
0345           ${RegistryWrite} "HKCR\$R1\shell\open\command" "backup_val" '$1' '$0' '$2'; backup current value and its registery type
0346 NoProtocolBackup:
0347     WriteRegStr HKCR "$R1\shell\open\command" "" '"$R2" "%1"'  ; set our file association
0348 ;Goto VistaPlus
0349 
0350 ; TODO: type = startMenu or type = mime
0351 
0352 VistaPlus:
0353   ;Vista and newer need some more works
0354   AppAssocReg::SetAppAsDefault "${PRODUCT_NAME}" "$R1" "$R0"
0355 
0356 NotSupported:
0357   registry::_Unload
0358   !verbose pop
0359 !macroend
0360 
0361 !define UnRegisterAssociation `!insertmacro UnRegisterAssociationCall`
0362 !define un.UnRegisterAssociation `!insertmacro UnRegisterAssociationCall`
0363 
0364 !macro UnRegisterAssociation
0365 !macroend
0366 
0367 !macro un.UnRegisterAssociation
0368 !macroend
0369 
0370 !macro UnRegisterAssociation_
0371   !verbose push
0372   !verbose ${_AllAssociation_VERBOSE}
0373 
0374   Pop $R3 ;type = file or protocol
0375   Pop $R2 ;prog_id
0376   Pop $R1 ;exe
0377   Pop $R0 ;association name = ext or protocol
0378 
0379   StrCmp "$R3" "file" 0 NoFile
0380 ; file
0381           ReadRegStr $1 HKCR $R0 ""
0382           StrCmp $1 $R2 0 NoOwn ; only do this if we own it
0383           ReadRegStr $1 HKCR $R0 "backup_val"
0384           StrCmp $1 "" 0 RestoreFile ; if backup="" then delete the whole key
0385           Push `"No ProgId Pushed"`
0386           DeleteRegKey HKCR $R0
0387           Goto NoOwn
0388 
0389         RestoreFile:
0390           Push `$1`
0391           WriteRegStr HKCR $R0 "" $1
0392           DeleteRegValue HKCR $R0 "backup_val"
0393           DeleteRegKey HKCR $R2 ;Delete key with association name settings
0394           Goto NoOwn
0395 
0396 NoFile:
0397 ; Protocol
0398   StrCmp "$R3" "protocol" 0 NoOwn
0399           ReadRegStr $1 HKCR "$R0\shell\open\command" ""
0400           StrCmp $1 '"$R1" "%1"' 0 NoOwn ; only do this if we own it
0401           ; ReadRegStr $1 HKCR "$R0\shell\open\command" "backup_val"
0402           ${RegistryRead} "HKEY_CLASSES_ROOT\$R0\shell\open\command" "backup_val" '$1' '$0' ; read current protocol association and its registery type
0403           StrCmp $1 "" 0 RestoreProtocol ; if backup="" then delete the whole key
0404           Push `"No ProgId Pushed"`
0405           DeleteRegKey HKCR "$R0\shell\open\command"
0406           Goto NoOwn
0407 
0408         RestoreProtocol:
0409           ReadRegStr $2 HKCR "$R0\shell\open\command" "backup_progid"
0410           StrCmp $2 "" 0 HasProgId
0411             Push `"No ProgId Pushed"`
0412             Goto NoProgID
0413           HasProgId:
0414             Push `$2`
0415         NoProgID:
0416           ;WriteRegStr HKCR "$R0\shell\open\command" "" $1
0417           ${RegistryWrite} "HKEY_CLASSES_ROOT\$R0\shell\open\command" "" '$1' '$0' '$2'
0418           DeleteRegValue HKCR "$R0\shell\open\command" "backup_val"
0419           DeleteRegValue HKCR "$R0\shell\open\command" "backup_progid"
0420       StrCmp $R2 "" NoOwn 0 ;Delete protocol association if it's present
0421             DeleteRegKey HKCR $R2 ;Delete key with association name settings
0422 ;Goto NoOwn
0423 
0424 ; TODO: type = startMenu or type = mime
0425 
0426  NoOwn:
0427   registry::_Unload
0428   !verbose pop
0429 !macroend
0430 
0431 !define UpdateSystemIcons `!insertmacro UpdateSystemIcons_`
0432 !define un.UpdateSystemIcons `!insertmacro UpdateSystemIcons_`
0433 
0434 !macro UpdateSystemIcons
0435 !macroend
0436 
0437 !macro un.UpdateSystemIcons
0438 !macroend
0439 
0440  ; !defines for use with SHChangeNotify
0441 !ifdef SHCNE_ASSOCCHANGED
0442   !undef SHCNE_ASSOCCHANGED
0443 !endif
0444 !define SHCNE_ASSOCCHANGED 0x08000000
0445 
0446 !ifdef SHCNF_FLUSHNOWAIT
0447   !undef SHCNF_FLUSHNOWAIT
0448 !endif
0449 !define SHCNF_FLUSHNOWAIT        0x3000
0450 
0451 !macro UpdateSystemIcons_
0452 ; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
0453 ; can update the shell.
0454   System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSHNOWAIT}, 0, 0)"
0455 !macroend
0456 !endif # !AllAssociation_INCLUDED