2010-06-14 17 views
15

NSIS tiene una variable Nombre que defina en el guión:NSIS - poner versión EXE en nombre del instalador

Name "MyApp" 

Se define el nombre del instalador, que consigue muestra como el título de la ventana, etc.

¿Hay alguna forma de extraer el número de versión de .NET de mi EXE principal y anexarlo al Nombre?

Así que mi nombre sería instalador automáticamente 'V2.2.0.0" MiApl o lo que sea?

Respuesta

22

Puede ser una forma muy simple de hacer esto, pero yo no sé lo que es. Cuando Primero comencé a usar NSIS, desarrollé esta solución para satisfacer mis necesidades y no volví a visitar el problema para ver si hay algo más elegante.

Quería que mis instaladores tuvieran el mismo número de versión, descripción e información de derechos de autor que mi ejecutable principal. Así que escribí una aplicación corta de C# llamada GetAssemblyInfoForNSIS que extrae esa información del archivo de un ejecutable y la escribe en un archivo .nsh que incluyen mis instaladores.

Aquí está la aplicación de 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"); 
      } 
     } 
    } 
} 

tanto, si utiliza esa aplicación, así:

GetAssemblyInfoForNSIS.exe MyApp.exe MyAppVersionInfo.nsh

que se obtendría una archivo denominado MyAppVersionInfo.nsh que se parece a esto (suponiendo que esta información se encuentre en el archivo ejecutable):

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

En la parte superior de mi script NSIS, hago algo como esto:

!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 

El primer 3 define el conjunto de los nombres de archivo a utilizar en el !system llamada a GetAssemblyInfoForNSIS.exe. Esta llamada al sistema se lleva a cabo durante la compilación de su instalador y genera el archivo .nsh justo antes de incluirlo. Uso el modificador/NONFATAL para que mi instalador no falle por completo si se produce un error al generar el archivo de inclusión.

+0

ahora que es lo que llamo una solución! Gracias:) – codeulike

+0

Las personas como tú son la razón por la que SO funciona :) Gracias – darkpbj

8

Puede hacer esto sin .NET mediante la GetVersion plugin, pero siguiendo la misma lógica básica:

Aquí es 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 

a recopilar la información una vez, y luego desde el cual lo su verdadera instalador:

; 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" 
+0

Manera sorprendentemente limpia de hacerlo, gracias –

+0

Sería realmente interesante saber: ¿Por qué es necesario compilar un exe en lugar de solo incluir algún código? – FourtyTwo

1

Puede lograr esto usando MSBuild.

  1. acaba de añadir su guión .nsi proyectar y establecer esta propiedad Copy to Output Directory valor Copy always o Copy if newer archivo. (. Ej .csproj o vbproj)

  2. Añadir al archivo de proyecto siguiente código (suponga que el script nsi tiene nombre 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. Uso $Version variable en su secuencia de comandos nsi:

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

Escritura VBS simple de llamada después de NSIS compi LE:

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

Desde NSISv3.0 esto se puede hacer con !getddlversion sin utilizar ningún software de terceros:

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