NSIS - 将EXE版本放入安装程序的名称

时间:2010-06-14 16:36:15

标签: nsis

NSIS有一个您在脚本中定义的Name变量:

Name "MyApp"

它定义了安装程序的名称,它显示为窗口标题等。

有没有办法从我的主EXE中提取.NET版本号并将其附加到名称?

这样我的安装程序名称会自动成为“MyApp V2.2.0.0”或其他什么?

7 个答案:

答案 0 :(得分:22)

可能有一种非常简单的方法可以做到这一点,但我不知道它是什么。当我第一次开始使用NSIS时,我开发了这种解决方法以满足我的需求,并且没有重新讨论这个问题,因为看看是否有更优雅的东西。

我希望我的安装程序具有与我的主要可执行文件相同的版本号,说明和版权信息。所以我编写了一个名为GetAssemblyInfoForNSIS的简短C#应用程序,它从可执行文件中提取该文件信息,并将其写入我的安装程序所包含的.nsh文件中。

这是C#app:

using System;
using System.Collections.Generic;
using System.Text;

namespace GetAssemblyInfoForNSIS {
    class Program {
        /// <summary>
        /// This program is used at compile-time by the NSIS Install Scripts.
        /// It copies the file properties of an assembly and writes that info a
        /// header file that the scripts use to make the installer match the program
        /// </summary>
        static void Main(string[] args) {
            try {
                String inputFile = args[0];
                String outputFile = args[1];
                System.Diagnostics.FileVersionInfo fileInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(inputFile);
                using (System.IO.TextWriter writer = new System.IO.StreamWriter(outputFile, false, Encoding.Default)) {
                    writer.WriteLine("!define VERSION \"" + fileInfo.ProductVersion + "\"");
                    writer.WriteLine("!define DESCRIPTION \"" + fileInfo.FileDescription + "\"");
                    writer.WriteLine("!define COPYRIGHT \"" + fileInfo.LegalCopyright + "\"");
                    writer.Close();
                }
            } catch (Exception e) {
                Console.WriteLine(e.Message + "\n\n");
                Console.WriteLine("Usage: GetAssemblyInfoForNSIS.exe MyApp.exe MyAppVersionInfo.nsh\n");
            }
        }
    }
}

因此,如果您像这样使用该应用程序:

  

GetAssemblyInfoForNSIS.exe MyApp.exe MyAppVersionInfo.nsh

你会得到一个名为MyAppVersionInfo.nsh的文件看起来像这样(假设这个信息在你的可执行文件中):

!define VERSION "2.0" 
!define DESCRIPTION "My awesome application"
!define COPYRIGHT "Copyright © Me 2010"

在我的NSIS脚本的顶部,我做了类似的事情:

!define GetAssemblyInfoForNSIS "C:\MyPath\GetAssemblyInfoForNSIS.exe"
!define PrimaryAssembly "C:\MyPath\MyApp.exe"
!define VersionHeader "C:\MyPath\MyAppVersionInfo.nsh"
!system '"${GetAssemblyInfoForNSIS}" "${PrimaryAssembly}" "${VersionHeader}"'
!include /NONFATAL "${VersionHeader}"

!ifdef VERSION
    Name "My App ${VERSION}"
!else
    Name "My App"
!endif

!ifdef DESCRIPTION
    VIAddVersionKey FileDescription "${DESCRIPTION}"
!endif

!ifdef COPYRIGHT
    VIAddVersionKey LegalCopyright "${COPYRIGHT}"
!endif

前3个定义设置要在GetAssemblyInfoForNSIS.exe的!system调用中使用的文件名。此系统调用在安装程序编译期间进行,并在包含之前生成.nsh文件。我使用/ NONFATAL开关,以便在生成包含文件时发生错误,我的安装程序不会完全失败。

答案 1 :(得分:11)

您可以使用GetVersion plugin在没有.NET的情况下执行此操作,但遵循相同的基本逻辑:

这是ExtractVersionInfo.nsi:

!define File "...\path\to\your\app.exe"

OutFile "ExtractVersionInfo.exe"
SilentInstall silent
RequestExecutionLevel user

Section

 ## Get file version
 GetDllVersion "${File}" $R0 $R1
  IntOp $R2 $R0 / 0x00010000
  IntOp $R3 $R0 & 0x0000FFFF
  IntOp $R4 $R1 / 0x00010000
  IntOp $R5 $R1 & 0x0000FFFF
  StrCpy $R1 "$R2.$R3.$R4.$R5"

 ## Write it to a !define for use in main script
 FileOpen $R0 "$EXEDIR\App-Version.txt" w
  FileWrite $R0 '!define Version "$R1"'
 FileClose $R0

SectionEnd

您编译一次,然后从真正的安装程序中调用它:

; We want to stamp the version of the installer into its exe name.
; We will get the version number from the app itself.
!system "ExtractVersionInfo.exe"
!include "App-Version.txt"
Name "My App, Version ${Version}"
OutFile "MyApp-${Version}.exe"

答案 2 :(得分:3)

答案 3 :(得分:3)

自NSISv3.0以来,可以使用!getddlversion完成此操作,而无需使用任何第三方软件:

!getdllversion "MyApp.exe" ver
Name "MyName ${ver1}.${ver2}.${ver3}.${ver4}"
OutFile "my_name_install_v.${ver1}.${ver2}.${ver3}.${ver4}.exe"

答案 4 :(得分:1)

您可以使用MSBuild实现此目的。

  1. 只需将.nsi脚本添加到项目并设置此文件属性即可 Copy to Output DirectoryCopy alwaysCopy if newer

  2. 在代码后添加到您的项目文件(例如.csproj或。vbproj)(假设您的nsi脚本名称为installer.nsi

    <Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Release'">
      <!-- Getting assembly information -->
      <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
        <Output TaskParameter="Assemblies" ItemName="myAssemblyInfo"/>
      </GetAssemblyIdentity>
      <!-- Compile NSIS installer script to get installer file -->
      <Exec Command='"%programfiles(x86)%\nsis\makensis.exe" /DVersion=%(myAssemblyInfo.Version) "$(TargetDir)installer.nsi"'>
        <!-- Just to show output from nsis to VS Output -->
        <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
      </Exec>
    </Target>
    
  3. $Version脚本中使用nsi变量:

    # define installer name
    OutFile "MyApp-${Version}.exe"
    

答案 5 :(得分:0)

在NSIS编译后调用简单的VBS脚本:

Set ddr = CreateObject("Scripting.FileSystemObject")
Version = ddr.GetFileVersion( "..\path_to_version.exe" )
ddr.MoveFile "OutputSetup.exe", "OutputSetup_" & Version & ".exe"

答案 6 :(得分:-1)

自NSIS v3.0a0起,您可以直接在脚本中进行操作,不需要任何外部工具:!getdllversion

示例代码(来自文档):

!getdllversion "$%WINDIR%\Explorer.exe" Expv_
!echo "Explorer.exe version is ${Expv_1}.${Expv_2}.${Expv_3}.${Expv_4}"