比较“已安装版本”与“待安装版本”

时间:2020-05-06 09:40:10

标签: nsis

已经使用NSIS(v3.05)了几周。做它需要做的事。我一直在追逐以下问题几天,却无法完全理解它。 问题陈述: 相互比较两(2)个版本。实现的方法很多。我选择了以下内容: 通过(函数)LineRead(!include TextFunc.nsh)从当前安装的版本.txt文件中检索第一个“版本”(字符串),如下所示:

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)

使用以下代码检索第二个“版本”:

!getdllversion "C:\...\application_name.exe" expversion_
StrCpy $7 ${expversion_}  # pass the define string 'expversion' to $7

最后一部分,我使用以下代码比较$ 4和$ 7:

${VersionCompare} $4 $7 $R0

仅当我确定'$ 4'(版本字符串#1)和'$ 7'(版本字符串#2)是VersionCompare的正确输入(输出:$ R0)时,这才有效

问题:是否有一种方法可以显示(用于测试/检查)$ 4的内容(@编译时间),以便确定var $ 4是否包含正确的字符串以传递给函数'VersionCompare'? (尝试过'DetailPrint $ 4';不会解析为预期的字符串(由函数'LineRead'检索)。)(我知道'DetailPrint'仅在执行安装'.exe文件时显示。所以没有看到@ compile是有道理的时间。)

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"

如何在编译期间将$ 4解析为版本字符串(出于测试目的)?

问题2: 我在函数中使用预处理器命令'!GetDLLVersion'来检索要安装的'app'版本的版本号(通过NSIS安装程序...)。 MakeNSIS显示正确的版本解析:

Function: "VersionRetrievalBinary"
!getdllversion: C:\1_SW_dev\...\app.exe (1.8.47.5)->(expversion_<1..4>)

问题:“ expverion_”到底是什么?变量还是定义?如果是定义(我在这里阅读=> Reference/!getdllversion),是否需要在脚本中按以下方式定义它?:

!define expverion_1 " "  # Major; single digit
!define expverion_2 "  "  # Minor; 2-digit
!define expverion_3 "   " # Build; 3-digit
!define expverion_4 "   "# Revision; 3-digit

不确定“ expversion_”的确切含义并进行操作/运行,MakeNSIS会发出以下警告,即-我认为-显然表明存在错误:

warning 6000: unknown variable/constant "{expversion_}" detected, ignoring (C:\1_SW_dev\...\app_client.nsi:295)

令人担忧的部分是MakeNSIS编译消息中的单词“ 忽略”。我能否从上述警告消息中得出结论,将通过名称“ expversion_”从(定义?)派生的字符串分配不会通过命令传递给var $ 7:

StrCpy $7 ${expversion_}

出现以下MakeNSIS消息(@编译时间)以确认这一点:

StrCpy $7 "${expversion_}" () ()

它似乎可以解决空白问题(不确定我是否正确阅读了此MakeNSIS消息)。

尽管在NSIS方面学到了很多东西(并且很喜欢),并且阅读了大多数相关文档,但我并没有对此有所了解。

提前通过thnx解决这一难题。

我自己解决了这个难题。 版本比较的解决方案相当“简单”。此处的重要部分:(添加到.onInit)

  1. 创建一个函数(例如名称'VersionComparison')
  2. 从注册表中读取本地版本
  3. 从二进制文件(例如.DLL或.exe)中“读取”安装版本
  4. 使用VersionCompare(!include WordFunc.nsh)进行实际比较。

1 个答案:

答案 0 :(得分:0)

我将首先解决!getdllversion问题。它从version info block的开头提取4个16位数字,并将它们存储在4个定义中。命名定义时,它只使用您传入的名称加上一个数字。

!getdllversion "$%windir%\explorer.exe" foo
!warning ${foo2} ; This prints the minor version

您的注释中没有特定的数字位数。 4个数字中的每个数字都从0到65535。

您可以在编译时对这些数字进行基本验证:

!if ${foo1} < 1
!error "Major version must at least be 1, we don't ship beta software :) " 
!endif

第二个问题很难解决。仅当安装程序正在运行时才能扩展变量。唯一的选择是从主.nsi内部实际生成并运行“安装程序”:

!makensis vertest.nsi = 0
!execute '"$%temp%\vertest.exe" /S' = 0
!defile "$%temp%\vertest.exe" 

vertest.nsi的外观类似于

OutFile "$%temp%\vertest.exe" 
RequestExecutionLevel user
SilentInstall silent

Section
Do version test here and Goto.. 
fail:
Abort
success:
SectionEnd