Have been working with NSIS (v3.05) for a few weeks. Does what it needs to do. I have been chasing the following problem for a few days and have not been able to comprehend it completely. Problem statement: Compare two (2) versions with each other. Many ways to implement. I chose the following: 1st 'version' (string) is retrieved from the currently installed versions .txt file via (function) LineRead (!include TextFunc.nsh) like this:
IfFileExists "C:\$PROGRAMFILES64\...\VERSION.txt" 0 +31 # Open the file and perform N FileRead
DetailPrint "VERSION.txt found!"
${LineRead} "C:\$PROGRAMFILES64\...\VERSION.txt" "7" $4 # $4 = '1.x.y.z' (for example)
2nd 'version' is retrieved with following code:
!getdllversion "C:\...\application_name.exe" expversion_
StrCpy $7 ${expversion_} # pass the define string 'expversion' to $7
As last part I use following code for comparison of $4 and $7:
${VersionCompare} $4 $7 $R0
This can only work as I know for sure that '$4' (version string #1) and '$7' (version string #2) are correct inputs for VersionCompare (output: $R0)
Question: Is there a way to display (for test/check) the content of $4 (@ compile time) in order to know for sure var $4 contains the correct string to be passed to function 'VersionCompare'? (tried 'DetailPrint $4'; does not resolve into the expected string (retrieved by function 'LineRead'). (I know that 'DetailPrint' only displays during executing the installation '.exe. file So is makes sense not seeing that @ compile time.)
Output from MakeNSIS:
IfFileExists: "C:\$PROGRAMFILES64\...\VERSION.txt" ? 0 : +31
DetailPrint: "VERSION.txt found!"
!insertmacro: LineReadCall
!insertmacro: end of LineReadCall
DetailPrint: "The version number of the currently installed app: $4"
How-To get $4 resolve into the version string (for testing purposes) during compile time)?
Question number 2: I use the preprocessor command '!GetDLLVersion' in a function to retrieve version number of the to be installed version of the 'app' (via The NSIS Installer...). MakeNSIS displays resolving the version correctly:
Function: "VersionRetrievalBinary"
!getdllversion: C:\1_SW_dev\...\app.exe (1.8.47.5)->(expversion_<1..4>)
Question: What exactly is 'expverion_'?; a var or a define? If a define (which I read here => Reference/!getdllversion), do I need to define it in my script as follow?:
!define expverion_1 " " # Major; single digit
!define expverion_2 " " # Minor; 2-digit
!define expverion_3 " " # Build; 3-digit
!define expverion_4 " "# Revision; 3-digit
Being unsure what 'expversion_' exactly is and operates/works MakeNSIS throws following warning that -I think- indicates clearly something is incorrect:
warning 6000: unknown variable/constant "{expversion_}" detected, ignoring (C:\1_SW_dev\...\app_client.nsi:295)
The worrying part is the word 'ignoring' in the MakeNSIS compiling message. Can I conclude from above mentioned warning message that assigning the string derived from the (define?) with name "expversion_" is not passed to var $7 by means of command:
StrCpy $7 ${expversion_}
Following MakeNSIS message (@ compile time) appears to confirm this:
StrCpy $7 "${expversion_}" () ()
It appears to resolve empty (unsure if I read this MakeNSIS message correctly).
Although having learned a lot wrt NSIS (and liking it) and gone through most of the relevant documentation I do not get my head around this one.
Thnx in advance for solving this specific piece of the puzzle.
Have solved the puzzle myself. The solution to a version comparison is rather 'simple'. The essential parts herewith: (add to .onInit)
I'll tackle the !getdllversion
issue first. It extracts the 4 16-bit numbers from the start of the version info block and stores them in 4 defines. It simply uses the name you pass in plus a number when naming the defines.
!getdllversion "$%windir%\explorer.exe" foo
!warning ${foo2} ; This prints the minor version
There is no specific number of digits as expected by your comments. Each of the 4 numbers go from 0 to 65535.
You can do basic verification of these numbers at compile time:
!if ${foo1} < 1
!error "Major version must at least be 1, we don't ship beta software :) "
!endif
The 2nd problem is harder to solve. Variables can only be expanded when the installer is running. The only option is to actually generate and run a "installer" from inside your main .nsi:
!makensis vertest.nsi = 0
!execute '"$%temp%\vertest.exe" /S' = 0
!defile "$%temp%\vertest.exe"
where vertest.nsi would look something like
OutFile "$%temp%\vertest.exe"
RequestExecutionLevel user
SilentInstall silent
Section
Do version test here and Goto..
fail:
Abort
success:
SectionEnd