自动检索EXE文件版本以嵌入NSIS安装程序元数据

use*_*939 7 versioning metadata nsis

我试图通过从我的可执行文件(在这种情况下,.NET应用程序)中自动检索版本信息来删除应用程序发布过程中的另一个步骤.

到目前为止,我已经能够获得有限的NSIS知识,但我很快就知道这还不够.

第1步:在可执行文件中声明版本信息

在AssemblyInfo.cs中,我声明[assembly: AssemblyVersion("1.0.0.1")].这成功地使版本信息出现在已编译的可执行文件中(在"文件版本"和"产品版本"下).

第2步:从可执行文件中检索版本信息

根据关于"GetFileVersion"的这篇文章,导入"FileFunc.nsh"允许您从可执行文件中检索版本信息.

使用的代码:

Section
    Var /GLOBAL version
    ${GetFileVersion} "C:\test.exe" $version
    ...
SectionEnd
Run Code Online (Sandbox Code Playgroud)

第3步:验证函数调用的内容

根据文档的5.1.7节,我应该能够在编译期间使用"!echo"命令打印到命令行.打印变量(或常量等)的内容之间的区别仍然让我困惑,所以我尝试了所有这四个选项:

!echo $version
!echo "$version"
!echo "${version}"
!echo ${version}
Run Code Online (Sandbox Code Playgroud)

这导致:

$version (InstallScript.nsi:15)
$version (InstallScript.nsi:16)
${version} (InstallScript.nsi:17)
${version} (InstallScript.nsi:18)
Run Code Online (Sandbox Code Playgroud)

第4步:声明安装程序元数据

根据4.8.3节,我应该可以通过VIProductVersion和添加安装程序元数据VIAddVersionKey.

VIProductVersion $version 
VIAddVersionKey "FileVersion" "$version"
Run Code Online (Sandbox Code Playgroud)

在构建的安装程序中,这会将字符串"$ version"添加到指定的字段中.


ToString()在NSIS中是否有相同的东西?如何访问变量的内容?变量名的打印是否意味着它没有内容?如何验证是否GetFileVersion正确调用,正确执行并返回值?

And*_*ers 12

编辑:NSIS v3现在包含一个!getdllversion预处理器指令,如果您仍在使用NSIS v2,则只需要GetVersionLocal解决方法.

有计划在NSIS 2.47 本地使用!getdllversion ,现在你必须使用这个解决方法:

outfile test.exe
requestexecutionlevel user

!macro GetVersionLocal file basedef
!verbose push
!verbose 1
!tempfile _GetVersionLocal_nsi
!tempfile _GetVersionLocal_exe
!appendfile "${_GetVersionLocal_nsi}" 'Outfile "${_GetVersionLocal_exe}"$\nRequestexecutionlevel user$\n'
!appendfile "${_GetVersionLocal_nsi}" 'Section$\n!define D "$"$\n!define N "${D}\n"$\n'
!appendfile "${_GetVersionLocal_nsi}" 'GetDLLVersion "${file}" $2 $4$\n'
!appendfile "${_GetVersionLocal_nsi}" 'IntOp $1 $2 / 0x00010000$\nIntOp $2 $2 & 0x0000FFFF$\n'
!appendfile "${_GetVersionLocal_nsi}" 'IntOp $3 $4 / 0x00010000$\nIntOp $4 $4 & 0x0000FFFF$\n'
!appendfile "${_GetVersionLocal_nsi}" 'FileOpen $0 "${_GetVersionLocal_nsi}" w$\nStrCpy $9 "${N}"$\n'
!appendfile "${_GetVersionLocal_nsi}" 'FileWrite $0 "!define ${basedef}1 $1$9"$\nFileWrite $0 "!define ${basedef}2 $2$9"$\n'
!appendfile "${_GetVersionLocal_nsi}" 'FileWrite $0 "!define ${basedef}3 $3$9"$\nFileWrite $0 "!define ${basedef}4 $4$9"$\n'
!appendfile "${_GetVersionLocal_nsi}" 'FileClose $0$\nSectionend$\n'
!system '"${NSISDIR}\makensis" -NOCD -NOCONFIG "${_GetVersionLocal_nsi}"' = 0
!system '"${_GetVersionLocal_exe}" /S' = 0
!delfile "${_GetVersionLocal_exe}"
!undef _GetVersionLocal_exe
!include "${_GetVersionLocal_nsi}"
!delfile "${_GetVersionLocal_nsi}"
!undef _GetVersionLocal_nsi
!verbose pop
!macroend

!insertmacro GetVersionLocal "$%windir%\Explorer.exe" MyVer_
VIProductVersion "${MyVer_1}.${MyVer_2}.${MyVer_3}.${MyVer_4}"
VIAddVersionKey "FileVersion" "${MyVer_1}.${MyVer_2}.${MyVer_3}.${MyVer_4}"

page instfiles
section
sectionend
Run Code Online (Sandbox Code Playgroud)

这个宏:

  1. 创建临时.nsi文件
  2. 将临时.nsi编译为临时可执行文件
  3. 运行临时.exe
  4. 删除这两个文件(.nsi和.exe)
  5. 返回包含指定可执行文件的版本信息的数组.


ycl*_*vnc 9

更新的信息:

NSIS现在包括!getdllversion命令,它执行相同的操作.用法:

!getdllversion "$%windir%\explorer.exe" expv_
!echo "Explorer.exe version is ${expv_1}.${expv_2}.${expv_3}.${expv_4}"
Run Code Online (Sandbox Code Playgroud)

更新:!getdllversion命令是一个"编译时命令",它与GetDLLVersion指令不同.IMO应该被命名为!getdllversionlocal以防止混淆,因为它类似于GetDLLVersionLocal指令,而不是GetDLLVersion

在NSIS 3.0a1中包含的用户手册中,它说:

5.1.14!getdllversion

localfilename define_basename

这与GetDLLVersionLocal类似,只是它将版本号存储在定义中,因此可以在任何地方使用,而不仅仅是在函数和部分内部.

!getdllversion "$%windir%\explorer.exe" expv_
!echo "Explorer.exe version is ${expv_1}.${expv_2}.${expv_3}.${expv_4}"
Run Code Online (Sandbox Code Playgroud)

  • @EricLaw:不,它在_building system_上得到了回报; 来自NSIS用户手册:这与GetDLLVersionLocal类似,只是它将版本号存储在定义中,因此可以在任何地方使用,而不仅仅是在函数和部分内部.不是:此部分目前不存在于在线手册中,仅存在于NSIS安装的用户手册中. (2认同)