比较“已安装版本”与 'to-be-installed-version'

Compare 'installed-version'versus 'to-be-installed-version'

已经使用 NSIS (v3.05) 几个星期了。做它需要做的事。这几天一直在追下面的问题,一直没能完全领悟。 问题陈述: 相互比较两 (2) 个版本。多种实现方式。我选择了以下内容: 第一个 'version'(字符串)通过(函数)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"   #  = '1.x.y.z' (for example)

第二个 'version' 使用以下代码检索:

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

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

${VersionCompare}   $R0

这只有在我确定“$4”(版本字符串 #1)和“$7”(版本字符串 #2)是 VersionCompare(输出:$R0)的正确输入时才有效

问题:有没有办法显示(对于test/check)$4(@编译时)的内容,以便确定var $4包含要传递给函数的正确字符串'VersionCompare'? (已尝试 'DetailPrint ';未解析为预期的字符串(由函数 'LineRead' 检索)。(我知道 'DetailPrint' 仅在执行安装期间显示 '.exe. 文件 所以是有道理的没有看到那个@编译时间。)

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 解析为版本字符串(用于测试目的)?

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

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

问题:'expverion_'到底是什么?;一个 var 或一个定义?如果定义(我在这里阅读 => 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_' 到底是什么,operates/works MakeNSIS 抛出以下警告 - 我认为 - 清楚地表明某些地方不正确:

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

最担心的是MakeNSIS编译信息中的'ignoring'这个词。我可以从上面提到的警告消息中得出结论,分配从名称为 "expversion_" 的(定义?)派生的字符串不会通过命令传递给 var $7:

StrCpy  ${expversion_}

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

StrCpy  "${expversion_}" () ()

它似乎解析为空(不确定我是否正确阅读了这条 MakeNSIS 消息)。

虽然我已经从 NSIS 中学到了很多东西(并且喜欢它)并且阅读了大部分相关文档,但我还是不明白这一点。

提前解决这个特定的难题。

自己解开了这个谜题。 版本比较的解决方案是'simple'。重要部分如下:(添加到.onInit)

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

我会先解决 !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

第二个问题比较难解决。只有在安装程序 运行ning 时才能扩展变量。唯一的选择是从你的主 .nsi:

中实际生成 运行 一个 "installer"
!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