UpgradeDLL Func function: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
m (Updated author links.) |
m (Reverted edits by 125.20.12.21 to last version by Kichik) |
||
(7 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
{ | {{PageAuthor|opher}} | ||
== Description == | == Description == | ||
In my setup package I had to install 64 system files, which meant 64 !insertmacro UpgradeDLL ... lines :'( | In my setup package I had to install 64 system files, which meant 64 !insertmacro UpgradeDLL ... lines :'( | ||
So I wrote this function. It is capable of accepting a source directory (e.g. "$PLUGINSDIR\SysFiles") and a destination directory (e.g. $SYSDIR) and installing/upgrading all files in source with *one* function call. :) | So I wrote this function. It is capable of accepting a source directory (e.g. "$PLUGINSDIR\SysFiles") and a destination directory (e.g. $SYSDIR) and installing/upgrading all files in source with *one* function call. :) | ||
Requires [[Get extention of file]] | |||
== The Function == | == The Function == | ||
<highlight-nsis> | <highlight-nsis> | ||
!ifndef UPGRADEDLL_FUNC_INCLUDED | !ifndef UPGRADEDLL_FUNC_INCLUDED | ||
!define UPGRADEDLL_FUNC_INCLUDED | !define UPGRADEDLL_FUNC_INCLUDED | ||
; Function - Upgrade DLL File | ; Function - Upgrade DLL File | ||
; Written by Opher Shachar on 2004/01/14 | ; Written by Opher Shachar on 2004/01/14 | ||
; Revised on 2004/01/15: Supports registering *.TLB, *.OLB files with 'regtlib.exe' | ; Revised on 2004/01/15: Supports registering *.TLB, *.OLB files with 'regtlib.exe' | ||
; Needs 'GetFileExt' (http://nsis.sourceforge.net/ | ; Needs 'GetFileExt' (http://nsis.sourceforge.net/wiki/Get_extention_of_file) | ||
; $R6 now is | ; Revised 2007/02/06: fix directory as source, skip '.' and '..' entries | ||
; $R6 now is VOLATILE | |||
; Based on macro by Joost Verburg | ; Based on macro by Joost Verburg | ||
; -------------------------------------- | ; -------------------------------------- | ||
Line 31: | Line 29: | ||
; use this directory. | ; use this directory. | ||
; $R6 = REGISTER - if you want to upgrade a DLL that has to be registered. | ; $R6 = REGISTER - if you want to upgrade a DLL that has to be registered. | ||
; 0 = Don't register, anything else = Register -- note: | ; 0 = Don't register, anything else = Register -- note: VOLATILE | ||
; $R7 = LOCALFILE - Location of the new DLL file (on the user's system) | ; $R7 = LOCALFILE - Location of the new DLL file (on the user's system) | ||
; OR LOCALDIR - Source directory of newer DLLs | ; OR LOCALDIR - Source directory of newer DLLs | ||
Line 83: | Line 81: | ||
Push $0 | Push $0 | ||
Push $1 | Push $1 | ||
Push $2 | |||
StrCpy $1 $R7 | StrCpy $1 $R7 | ||
StrCpy $2 $R4 | |||
FindFirst $0 $R0 "$1\*.*" | FindFirst $0 $R0 "$1\*.*" | ||
Line 89: | Line 89: | ||
IfErrors upgradedll.nomore | IfErrors upgradedll.nomore | ||
StrCpy $R7 "$1\$R0" | StrCpy $R7 "$1\$R0" | ||
Call :upgradedll.doit | StrCpy $R4 "$2\$R0" | ||
StrCmp $R0 "." +3 | |||
StrCmp $R0 ".." +2 | |||
Call :upgradedll.doit | |||
FindNext $0 $R0 | FindNext $0 $R0 | ||
Goto loop | Goto loop | ||
Line 96: | Line 99: | ||
FindClose $0 | FindClose $0 | ||
StrCpy $R7 $1 | StrCpy $R7 $1 | ||
StrCpy $R4 $2 | |||
Pop $2 | |||
Pop $1 | Pop $1 | ||
Pop $0 | Pop $0 | ||
Line 213: | Line 218: | ||
!endif | !endif | ||
</highlight-nsis> | </highlight-nsis> | ||
[[Category:DLL, OCX, TLB Functions]] |
Latest revision as of 14:25, 24 March 2009
Author: opher (talk, contrib) |
Description
In my setup package I had to install 64 system files, which meant 64 !insertmacro UpgradeDLL ... lines :'( So I wrote this function. It is capable of accepting a source directory (e.g. "$PLUGINSDIR\SysFiles") and a destination directory (e.g. $SYSDIR) and installing/upgrading all files in source with *one* function call. :)
Requires Get extention of file
The Function
!ifndef UPGRADEDLL_FUNC_INCLUDED !define UPGRADEDLL_FUNC_INCLUDED ; Function - Upgrade DLL File ; Written by Opher Shachar on 2004/01/14 ; Revised on 2004/01/15: Supports registering *.TLB, *.OLB files with 'regtlib.exe' ; Needs 'GetFileExt' (http://nsis.sourceforge.net/wiki/Get_extention_of_file) ; Revised 2007/02/06: fix directory as source, skip '.' and '..' entries ; $R6 now is VOLATILE ; Based on macro by Joost Verburg ; -------------------------------------- ; ; Parameters: ; $R4 = DESTFILE - Location of the DLL file that should be upgraded (on user's system) ; OR DESTDIR - Target directory for upgraded DLLs ; $R5 = TEMPBASEDIR - Directory on the user's system to store a temporary file when ; the system has to be rebooted. ; For Win9x support, this should be on the same volume as the DESTFILE! ; The Windows temp directory could be located on any volume, so you cannot ; use this directory. ; $R6 = REGISTER - if you want to upgrade a DLL that has to be registered. ; 0 = Don't register, anything else = Register -- note: VOLATILE ; $R7 = LOCALFILE - Location of the new DLL file (on the user's system) ; OR LOCALDIR - Source directory of newer DLLs ; Note: If you want to support Win9x, you can only use short filenames (8.3). ; ; Example of usage for single file: ; $R4 = "$SYSDIR\dllname.dll" ; $R5 = "$SYSDIR" ; $R6 = "1" (= Register DLL) ; $R7 = "Source_dir\dllname.dll" ; Call UpgradeDLL_Func ; ; Example of usage with File command: ; SetOutPath "$PLUGINSDIR\SysFiles" ; File /r "sys_files_to_be_installed\*.*" ... ; ... ; File "some_other_sys_file.dll" ; $R4 = "$SYSDIR" -- note no '\', MUST be an existing directory ; $R5 = "$SYSDIR" ; $R6 = "1" (= Register DLL) ; $R7 = "$PLUGINSDIR\SysFiles" -- note no '\' ; Call UpgradeDLL_Func ; RMDir /r "$PLUGINSDIR\SysFiles" ; ; Example of usage for whole bunch of external files: ; $R4 = "$SYSDIR" -- note no '\', MUST be an existing directory ; $R5 = "$SYSDIR" ; $R6 = "1" (= Register DLL) ; $R7 = "Source_dir" -- note no '\' ; Call UpgradeDLL_Func Function UpgradeDLL_Func Push $R0 Push $R1 Push $R2 Push $R3 SetOverwrite try ;------------------------ ;Check single file IfFileExists "$R7\*.*" +3 Call :upgradedll.doit Goto upgradedll.end ;------------------------ ;Enumerate directory Push $0 Push $1 Push $2 StrCpy $1 $R7 StrCpy $2 $R4 FindFirst $0 $R0 "$1\*.*" loop: IfErrors upgradedll.nomore StrCpy $R7 "$1\$R0" StrCpy $R4 "$2\$R0" StrCmp $R0 "." +3 StrCmp $R0 ".." +2 Call :upgradedll.doit FindNext $0 $R0 Goto loop upgradedll.nomore: FindClose $0 StrCpy $R7 $1 StrCpy $R4 $2 Pop $2 Pop $1 Pop $0 Goto upgradedll.end ;------------------------ ;Do we want to register file? upgradedll.doit: IntCmp $R6 0 upgradedll.moveon ;------------------------ ;Is file a .TLB? == Use 'regtlib.exe' instead of 'RegDLL' Push $R4 Call GetFileExt Pop $R0 StrCmp $R0 "TLB" +2 StrCmp $R0 "OLB" 0 +3 StrCpy $R6 -1 Goto upgradedll.moveon StrCpy $R6 1 ;------------------------ ;File already installed? No. Just copy upgradedll.moveon: IfFileExists $R4 0 upgradedll.copy ;------------------------ ;Check file and version ClearErrors GetDLLVersion $R7 $R0 $R1 GetDLLVersion $R4 $R2 $R3 IfErrors upgradedll.upgrade IntCmpU $R0 $R2 0 upgradedll.done upgradedll.upgrade IntCmpU $R1 $R3 upgradedll.noreboot upgradedll.done upgradedll.upgrade ;------------------------ ;Let's upgrade the DLL! upgradedll.upgrade: IntCmp $R6 1 0 +2 +2 UnRegDLL $R4 ;Unregister the DLL ;------------------------ ;Try to copy the DLL directly upgradedll.copy: ClearErrors StrCpy $R0 $R4 Call :upgradedll.file IfErrors 0 upgradedll.noreboot ;------------------------ ;DLL is in use. Copy it to a temp file and Rename it on reboot. GetTempFileName $R0 $R5 Call :upgradedll.file Rename /REBOOTOK $R0 $R4 ;------------------------ ;Register the DLL on reboot IntCmp $R6 0 upgradedll.done IntCmp $R6 1 +3 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \ "Register $R4" '"$SYSDIR\regtlib.exe" "$R4"' Goto upgradedll.done WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \ "Register $R4" '"$SYSDIR\rundll32.exe" "$R4",DllRegisterServer' Goto upgradedll.done ;------------------------ ;Register the DLL upgradedll.noreboot: IntCmp $R6 0 upgradedll.done IntCmp $R6 1 +3 ExecWait '"$SYSDIR\regtlib.exe" "$R4"' Goto upgradedll.done RegDLL $R4 ;------------------------ ;Done upgradedll.done: Return ;------------------------ ;Called to copy the DLL upgradedll.file: CopyFiles /silent $R7 $R0 Return ;------------------------ ;End upgradedll.end: Pop $R3 Pop $R2 Pop $R1 Pop $R0 ;------------------------ ;Restore settings SetOverwrite lastused FunctionEnd !endif