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

时间:2011-11-18 20:22:42

标签: metadata versioning nsis

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

到目前为止,我已经能够通过对NSIS的有限知识了解,但我很快就知道这还不够。

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

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

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

根据此article on "GetFileVersion",导入" FileFunc.nsh"允许您从可执行文件中检索版本信息。

使用的代码:

Section
    Var /GLOBAL version
    ${GetFileVersion} "C:\test.exe" $version
    ...
SectionEnd

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

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

!echo $version
!echo "$version"
!echo "${version}"
!echo ${version}

这导致:

$version (InstallScript.nsi:15)
$version (InstallScript.nsi:16)
${version} (InstallScript.nsi:17)
${version} (InstallScript.nsi:18)

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

基于section 4.8.3,我应该可以通过VIProductVersionVIAddVersionKey添加安装程序元数据。

VIProductVersion $version 
VIAddVersionKey "FileVersion" "$version"

在构建的安装程序中,这会添加字符串" $ version"进入指定的字段。


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

2 个答案:

答案 0 :(得分:11)

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

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

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

这个宏:

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

答案 1 :(得分:9)

更新信息:

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

!getdllversion "$%windir%\explorer.exe" expv_
!echo "Explorer.exe version is ${expv_1}.${expv_2}.${expv_3}.${expv_4}"

UPDATE !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}"