; Macro - Upgrade DLL File
; Written by Joost Verburg
; ------------------------
;
; Parameters:
; LOCALFILE - Location of the new DLL file (on the compiler system)
; DESTFILE - Location of the DLL file that should be upgraded
; (on the user's system)
; 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.
;
; Define REPLACEDLL_NOREGISTER if you want to upgrade a DLL that does not
; have to be registered.
;
; Note: If you want to support Win9x, you can only use
; short filenames (8.3).
;
; Example of usage:
; !insertmacro ReplaceDLL "dllname.dll" "$SYSDIR\dllname.dll" "$SYSDIR"
;
!macro ReplaceDLL LOCALFILE DESTFILE TEMPBASEDIR
Push $R0
Push $R1
Push $R2
Push $R3
Push $R4
Push $R5
;------------------------
;Unique number for labels
!define REPLACEDLL_UNIQUE ${__LINE__}
;------------------------
;Copy the parameters used on run-time to a variable
;This allows the usage of variables as parameter
StrCpy $R4 "${DESTFILE}"
StrCpy $R5 "${TEMPBASEDIR}"
;------------------------
;Check file and version
;
IfFileExists $R4 0 replacedll.copy_${REPLACEDLL_UNIQUE}
;ClearErrors
; GetDLLVersionLocal "${LOCALFILE}" $R0 $R1
; GetDLLVersion $R4 $R2 $R3
;IfErrors replacedll.upgrade_${REPLACEDLL_UNIQUE}
;
;IntCmpU $R0 $R2 0 replacedll.done_${REPLACEDLL_UNIQUE}
; replacedll.upgrade_${REPLACEDLL_UNIQUE}
;IntCmpU $R1 $R3 replacedll.done_${REPLACEDLL_UNIQUE}
; replacedll.done_${REPLACEDLL_UNIQUE}
; replacedll.upgrade_${REPLACEDLL_UNIQUE}
;------------------------
;Let's replace the DLL!
SetOverwrite try
;replacedll.upgrade_${REPLACEDLL_UNIQUE}:
!ifndef REPLACEDLL_NOREGISTER
;Unregister the DLL
UnRegDLL $R4
!endif
;------------------------
;Try to copy the DLL directly
ClearErrors
StrCpy $R0 $R4
Call :replacedll.file_${REPLACEDLL_UNIQUE}
IfErrors 0 replacedll.noreboot_${REPLACEDLL_UNIQUE}
;------------------------
;DLL is in use. Copy it to a temp file and Rename it on reboot.
GetTempFileName $R0 $R5
Call :replacedll.file_${REPLACEDLL_UNIQUE}
Rename /REBOOTOK $R0 $R4
;------------------------
;Register the DLL on reboot
!ifndef REPLACEDLL_NOREGISTER
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
"Register $R4" 'rundll32.exe "$R4",DllRegisterServer'
!endif
Goto replacedll.done_${REPLACEDLL_UNIQUE}
;------------------------
;DLL does not exist - just extract
replacedll.copy_${REPLACEDLL_UNIQUE}:
StrCpy $R0 $R4
Call :replacedll.file_${REPLACEDLL_UNIQUE}
;------------------------
;Register the DLL
replacedll.noreboot_${REPLACEDLL_UNIQUE}:
!ifndef REPLACEDLL_NOREGISTER
RegDLL $R4
!endif
;------------------------
;Done
replacedll.done_${REPLACEDLL_UNIQUE}:
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Pop $R0
;------------------------
;End
Goto replacedll.end_${REPLACEDLL_UNIQUE}
;------------------------
;Called to extract the DLL
replacedll.file_${REPLACEDLL_UNIQUE}:
File /oname=$R0 "${LOCALFILE}"
Return
replacedll.end_${REPLACEDLL_UNIQUE}:
;------------------------
;Restore settings
SetOverwrite lastused
!undef REPLACEDLL_UNIQUE
!macroend