;------------------------------------------------------------------------------ ; UpgradeFile (macro) ; Input: LOCAL_FILE = local file included in the installer ; TARGET_FILE = target file on user's system ; Output: $R0 = temporary file which is automatically deleted in most of cases ; ; Usage: ; ; !insertmacro UpgradeFile "LocalFilename" "TargetFilename" !macro UpgradeFile LOCAL_FILE TARGET_FILE SetDetailsPrint textonly ; disable detail list GetTempFileName $R0 ; extract local file temporarily SetOutPath $TEMP File /oname=$R0 ${LOCAL_FILE} Push ${TARGET_FILE} ; push target filename Call CompareAndUpgrade !macroend ;------------------------------------------------------------------------------ ; Function CompareAndUpgrade ; Updates a file based on GetFileVersion resource information. ; Input: top of stack = "file to be upgraded on target system" ; Output: none Function CompareAndUpgrade Exch $0 ; save original $0 and get input filename Push $1 ; save original $1 Push $2 ; save original $2 Push $R1 ; save original $R1 Push $R2 ; save original $R2 SetDetailsPrint textonly ; disable detail list x18sysinfoV0.1::GetFileVersion $0 ; get file version number in "A.B.C.D" format Pop $1 ; pop it to $1 x18sysinfoV0.1::GetFileVersion $R0 ; get local file version number in "A.B.C.D" format Pop $2 ; pop it to $2 SetDetailsPrint both ; enable detail list DetailPrint "Comparing file (version $2) ..."; print local version info StrCmp $1 "" 0 KnownVer ; branch according to known/unknown version DetailPrint "Found file $0 (version unknown)"; print unknown version info Goto LocalNewer ; skip version comparison KnownVer: DetailPrint "Found file $0 (version $1)" ; print version info StrCpy $R1 $1. ; add trailing dot delimiter to version number StrCpy $R2 $2. ; add trailing dot delimiter to local version number Call GetNextVerNumbers ; get MAJOR numbers ;DetailPrint "MAJOR=$1" IntCmpU $1 $2 0 LocalNewer LocalOlder ; compare MAJOR numbers Call GetNextVerNumbers ; get MINOR numbers ;DetailPrint "MINOR=$1" IntCmpU $1 $2 0 LocalNewer LocalOlder ; compare MINOR numbers Call GetNextVerNumbers ; get REVISION numbers ;DetailPrint "REVISION=$1" IntCmpU $1 $2 0 LocalNewer LocalOlder ; compare REVISION numbers Call GetNextVerNumbers ; get BUILD numbers ;DetailPrint "BUILD=$1" IntCmpU $1 $2 0 LocalNewer LocalOlder ; compare BUILD numbers DetailPrint "File versions equal" LocalOlder: DetailPrint "No need to upgrade file" Delete $R0 ; delete local file Goto UpgradeDone LocalNewer: IfFileExists $0 DoUnregFile DoNotUnregFile ; branch according to file existing/missing DoUnregFile: UnRegDLL $0 ; unregister target file Rename /REBOOTOK $R0 $0 ; rename local to target and reboot if necessary IfRebootFlag RegReboot RegNoReboot DoNotUnregFile: Rename $R0 $0 ; rename local to target Goto RegNoReboot RegReboot: WriteRegStr HKLM Software\Microsoft\Windows\CurrentVersion\RunOnce $0 "$SYSDIR\regsvr32 /s $0" Goto UpgradeDone RegNoReboot: RegDLL $0 ; register target file Delete $R0 ; delete local file UpgradeDone: Pop $R2 ; restore original $R2 Pop $R1 ; restore original $R1 Pop $2 ; restore original $2 Pop $1 ; restore original $1 Pop $0 ; restore original $0 FunctionEnd ;------------------------------------------------------------------------------ ; Function GetNextVerNumbers ; Input: $R1 = version number "A.B.C.D." ; $R2 = local version number "A.B.C.D." ; Output: $1 = number part A ; $R1 = remaining string of version number "B.C.D." ; $2 = local number part A ; $R2 = remaining string of local version number "B.C.D." Function GetNextVerNumbers Push $R1 ; push version number Call GetNextNumberPart ; get number part Pop $1 ; pop it Pop $R1 ; pop the remaining string Push $R2 ; push local version number Call GetNextNumberPart ; get local number part Pop $2 ; pop it Pop $R2 ; pop the remaining string FunctionEnd ;------------------------------------------------------------------------------ ; Function GetNextNumberPart ; Input: top of stack in format "1st.2nd.3rd.4th." ; Output: "1st" top of stack ; "2nd.3rd.4th." second entry of stack Function GetNextNumberPart Exch $0 ; save original $0 and get complex input string Push $1 ; save original $1 Push $2 ; save original $2 StrCpy $2 0 ; init counter=0 Loop: IntOp $2 $2 + 1 ; increment counter StrCpy $1 $0 1 $2 ; $1 now contains one char from input string by counter offset StrCmp $1 "" ExitLoop ; exit loop if end of string has been reached StrCmp $1 "." 0 Loop ; continue if "." dot delimiter was found, else repeat loop StrCpy $1 $0 $2 ; $1 now contains input string part til delimiter IntOp $2 $2 + 1 ; increment counter StrCpy $0 $0 "" $2 ; $0 now contains the remaining string ExitLoop: Pop $2 ; restore original $2 Push $0 ; store remaining string Exch 2 ; swap remaining string with original $0 Pop $0 ; restore original $0 Exch $1 ; restore original $1 and store string part til delimiter FunctionEnd