代码之家  ›  专栏  ›  技术社区  ›  codeulike

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

  •  16
  • codeulike  · 技术社区  · 15 年前

    NSIS 具有在脚本中定义的名称变量:

    Name "MyApp"
    

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

    有没有办法把.NET版本号从我的主EXE中拉出来并附加到名称中?

    所以我的安装程序名会自动变成“myappv2.2.0.0”或者别的什么?

    7 回复  |  直到 15 年前
        1
  •  22
  •   Kyle Gagnet    15 年前

    可能有一个非常简单的方法,但我不知道它是什么。当我第一次开始使用NSIS时,我开发了这个解决方法来满足我的需要,从那以后就再也没有重新讨论过这个问题,看看是否还有更优雅的东西。

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

    以下是C应用程序:

    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
    

    !system 调用GetAssemblyInfoForNSIS.exe。此系统调用在安装程序编译期间发生,并在包含.nsh文件之前生成该文件。我使用/NONFATAL开关,以便在生成include文件时发生错误时安装程序不会完全失败。

        2
  •  12
  •   Joshua Muskovitz    15 年前

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

    以下是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"
    
        3
  •  5
  •   default locale    7 年前

    !getddlversion

    !getdllversion "MyApp.exe" ver
    Name "MyName ${ver1}.${ver2}.${ver3}.${ver4}"
    OutFile "my_name_install_v.${ver1}.${ver2}.${ver3}.${ver4}.exe"
    
        4
  •  3
  •   Ashley Davis    13 年前
        5
  •  1
  •   Vadim Ovchinnikov    8 年前

    1. 只需添加你的 .nsi 编写脚本以投影并设置此文件属性 Copy to Output Directory Copy always Copy 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"
      
        6
  •  0
  •   themadmax    7 年前

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

    Set ddr = CreateObject("Scripting.FileSystemObject")
    Version = ddr.GetFileVersion( "..\path_to_version.exe" )
    ddr.MoveFile "OutputSetup.exe", "OutputSetup_" & Version & ".exe"
    
        7
  •  -1
  •   YePhIcK    7 年前

    由于NSIS v3.0a0可以直接在脚本中执行,因此不需要外部工具: !getdllversion

    示例代码(来自文档):

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