2010-06-14 33 views
15

NSIS có một biến Tên mà bạn xác định trong kịch bản:NSIS - đặt phiên bản EXE vào tên của trình cài đặt

Name "MyApp" 

Nó định nghĩa tên của trình cài đặt, mà được hiển thị như tiêu đề cửa sổ, vv

Có cách nào để kéo số Phiên bản .NET ra khỏi EXE chính của tôi và nối nó vào Tên không?

Vì vậy mà tên cài đặt của tôi sẽ tự động được 'V2.2.0.0" MyApp hay bất cứ điều gì?

Trả lời

22

Có thể có một cách rất đơn giản để làm điều này, nhưng tôi không biết nó là gì. Khi tôi đầu tiên bắt đầu sử dụng NSIS, tôi đã phát triển giải pháp này cho phù hợp với nhu cầu của mình và chưa xem xét lại vấn đề kể từ khi xem có điều gì thanh lịch hơn hay không. Vì vậy, tôi đã viết một ứng dụng C# ngắn gọi là GetAssemblyInfoForNSIS để lấy thông tin tệp đó từ tệp thực thi và ghi nó vào tệp .nsh mà trình cài đặt của tôi bao gồm.

Dưới đây là C# ứng dụng:

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"); 
      } 
     } 
    } 
} 

Vì vậy, nếu bạn sử dụng ứng dụng như vậy:

GetAssemblyInfoForNSIS.exe MyApp.exe MyAppVersionInfo.nsh

Bạn sẽ nhận được một tệp có tên MyAppVersionInfo.nsh trông giống như thế này (giả sử thông tin này nằm trong tệp thi hành của bạn):

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

Ở phía trên cùng của kịch bản NSIS của tôi, tôi làm điều gì đó như thế này:

!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 

Đầu tiên 3 định nghĩa thiết lập tên tập tin để sử dụng trong các cuộc gọi đến !system GetAssemblyInfoForNSIS.exe. Cuộc gọi hệ thống này diễn ra trong quá trình biên dịch của trình cài đặt và tạo tệp .nsh ngay trước khi bạn đưa nó vào. Tôi sử dụng công tắc/NONFATAL để trình cài đặt của tôi không hoàn toàn thất bại nếu xảy ra lỗi khi tạo tệp bao gồm.

+0

Bây giờ đó là những gì tôi gọi một giải pháp! Cảm ơn:) – codeulike

+0

Những người như bạn là lý do SO hoạt động :) Cảm ơn – darkpbj

8

Bạn có thể làm điều này mà không cần .NET bằng GetVersion plugin, nhưng sau cùng logic cơ bản:

Đây là 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 

Bạn biên dịch này một lần, và sau đó gọi nó từ trình cài đặt thực sự của bạn:

; 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

Đáng ngạc nhiên là cách làm sạch, nhờ –

+0

Thật thú vị khi biết: Tại sao cần phải biên dịch exe thay vì chỉ bao gồm một số mã? – FourtyTwo

3

tôi tìm thấy một cách để làm điều này trên wiki NSIS:

http://nsis.sourceforge.net/Version_Info_manipulations_on_compile-time

+1

Đó là một điều khá thú vị. Tôi thích cách v3.x mới của NSIS có thể thực hiện điều này thông qua, getdllversion và VIProductVersion/VIAddVersionKey. Tuy nhiên, đó là nếu có ai trên v3.x được nêu ra. – Damian

1

Bạn có thể đạt được điều này bằng cách sử dụng MSBuild.

  1. Chỉ cần thêm .nsi kịch bản của bạn để dự án và thiết lập thuộc tính Copy to Output Directory giá trị Copy always hoặc Copy if newer tập tin này. (. Ví dụ .csproj hoặc vbproj)

  2. Thêm vào tập tin dự án của bạn mã sau (giả sử nsi kịch bản của bạn có tên 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. Sử dụng $Version biến trong nsi kịch bản của bạn:

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

Gọi mã VBS đơn giản sau NSIS compi le:

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

Kể từ NSISv3.0 này có thể được thực hiện với !getddlversion mà không sử dụng bất kỳ phần mềm của bên thứ ba:

!getdllversion "MyApp.exe" ver 
Name "MyName ${ver1}.${ver2}.${ver3}.${ver4}" 
OutFile "my_name_install_v.${ver1}.${ver2}.${ver3}.${ver4}.exe" 
Các vấn đề liên quan