Archive: Check app version before installing


Check app version before installing
Hello

I'm installing .NET cSharp application

If necessary, I need to advice some user about version compatibility before installing. So I have to do some check before to replace an older version

What will be the best way to do that ?

Thanls for any help


if there's a reg key containing the version number you can use the easie way or you check the version by extracting the version number from a file (exe, dll aso) which is located by reading it's path from the registry.

Extract version number from file:

!define StrReplace '!insertmacro "_strReplaceConstructor"'

Var STR_REPLACE_VAR_0
Var STR_REPLACE_VAR_1
Var STR_REPLACE_VAR_2
Var STR_REPLACE_VAR_3
Var STR_REPLACE_VAR_4
Var STR_REPLACE_VAR_5
Var STR_REPLACE_VAR_6
Var STR_REPLACE_VAR_7
Var STR_REPLACE_VAR_8

!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
Push "${HAYSTACK}"
Push "${NEEDLE}"
Push "${NEEDLE2}"
Call StrReplace
Pop "${OUT}"
!macroend

Function StrReplace
Exch $STR_REPLACE_VAR_2
Exch 1
Exch $STR_REPLACE_VAR_1
Exch 2
Exch $STR_REPLACE_VAR_0
StrCpy $STR_REPLACE_VAR_3 -1
StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
loop:
IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
Goto loop
found:
StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
Goto loop
done:
Pop $STR_REPLACE_VAR_1
Pop $STR_REPLACE_VAR_1
Exch $STR_REPLACE_VAR_0
FunctionEnd

Function GetFileVersion
!define GetFileVersion `!insertmacro GetFileVersionCall`
!macro GetFileVersionCall _FILE _RESULT
Push `${_FILE}`
Call GetFileVersion
Pop ${_RESULT}
!macroend
Exch $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $6
ClearErrors
GetDllVersion '$0' $1 $2
IfErrors error
IntOp $3 $1 >> 16
IntOp $3 $3 & 0x0000FFFF
IntOp $4 $1 & 0x0000FFFF
IntOp $5 $2 >> 16
IntOp $5 $5 & 0x0000FFFF
IntOp $6 $2 & 0x0000FFFF
StrCpy $0 '$3.$4.$5.$6'
goto end
error:
SetErrors
StrCpy $0 ''
end:
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd

Function .onInit
StrCpy $R1 "0"
ReadRegStr $R0 HKLM "Software\DESiRED SOFTWARE" "installDir"
StrCmp $R0 "" NO_SW 0
IfFileExists "$R0\PROGRAM.EXE" 0 NO_EXE
StrCpy $R1 "1"
${GetFileVersion} "$R0\PROGRAM.EXE" $R2
${StrReplace} '$R3' '.' '' '$R2'
${if} $R3 == ""
MessageBox MB_OK "No version information found." IDOK Inst
${else}
${if} $R3 == "0815"
;MessageBox MB_OK "Compatible version found." IDOK Inst
Goto Inst
${else}
${if} $R3 <= "0815"
MessageBox MB_OK "SOFTWARE $R2 found.$\r$\nVersion 08.15 recommended." IDOK Inst
${else}
${if} $R3 >= "0815"
MessageBox MB_OK "SOFTWARE version 08.15 expected but version $R2 found." IDOK Inst
${else}
MessageBox MB_OK "Error extracting version number from file." IDOK Inst
${endif}
${endif}
${endif}
${endif}
NO_SW:
MessageBox MB_OK "SOFTWARE installation not found." IDOK Inst
GoTo Inst
NO_EXE:
MessageBox MB_OK "SOFTWARE installation found but FILE not found in given path." IDOK Inst
GoTo Inst
Inst:
FunctionEnd

i know, this code is quite a mess, but it works for me.
All dots are removed from the version number before comparing.

P.s.: Some of the $Rx vars are reused later so they may look unused in this example. But i only copied and pasted it. Sorry.

Thank you CG!

I will try that

Another Idea :

Do you know if there is a way to make a two step install
1- Install some DLL or piece of software
2- Run that dll to make some evaluation
3- Continue the install dependind dll return code ?


i'm sure it's possible with NSiS but i dunno how or if it's easie.
i would code my own executable that calls the DLL and sets an ErrorLevel on exit which can easiely be read by NSiS.
in most cases i use VB6 or C++ (due to no limitations by the need of no Framework), wrap it up inside NSiS and call it with ExecWait. Afterwards NSiS just reads the ErrorLevel.


You can call dll functions with the system plugin.


<<You can call dll functions with the system plugin>>

Hello

Thank for your reply

Can you give more explaination ...
Obviously the dll must already exist on the machine ?

What will be the process to install the dll, call it during the install process and allow some decision depending of the dll return code (abort installation for example)

Also can it be a .NET dll or must it be a native C dll


If you only need it once, just unpack your dll to a temp directory using the File command ($PLUGINSDIR would be an obvious choice), run the dll, then delete the dll again. How to call a dll function is explained and demonstrated in the system plugin readme.

If you want to register the dll, you could use regsvr32.exe for that, but there's also a standard macro described in the documentation (appendix B).

As for registering a .net dll, google is your friend.