[Azure DevOps] 使用 Inno Setup 制作桌面軟件安裝包


1. 桌面應用程序的 CI/CD

桌面應用程序的 CI/CD 過程和網站有一些不同,畢竟桌面應用程序的“部署”只是將安裝包分發到目標位置,連應用商店都不用上,根據公司的管理流程可以很復雜,也可以很簡單。在簡單的情況下,Azure Pipelines 中一個桌面應用(WPF)的 CI/CD 過程如下:

  1. 觸發器啟動 Pipeline
  2. 構建 WPF 應用程序
  3. 啟動單元測試以確保構建質量
  4. 創建安裝包
  5. 將安裝包復制到目標位置
  6. 通知用戶新安裝包已經可以獲取

使用 Azure Pipelines 實現 CI 這篇文章中,我講解了如何實現第 1、2、3、5 步。至於第 6 步,可以在 Project SettingsNotifications 頁面中設置使用郵件通知團隊成員,也可以參考 使用連接器接收Azure DevOps的通知 這篇文章通過 Teams 發送構建的結果。

現在我們還缺少第 4 步“創建安裝包”,這篇文章將講解如何在 Azure Pipelines 中使用 Inno Setup 創建安裝包。

2. 使用 Inno Setup 創建安裝包

假設我們已經根據 使用 Azure Pipelines 實現 CI 的做法發布了一個 WPF 應用程序,發布到 Artifacts 的文件將會如上圖所示,可以以 Zip 的方式將所有輸出文件下載到本地,基本相當於綠色版軟件。但我們不能將這個 Zip 包直接發給客戶,我們至少還要包括開始菜單和修改注冊表什么的一大堆東西,所以需要將 Release 的文件打包到一個安裝包中。我的公司通常使用 Inno Setup 制作安裝包,在 Azure Pipelines 中使用 Inno Setup 也十分簡單,於是這篇文章將使用 Inno Setup 作為制作安裝包的例子。

首先我們需要一個 iss 腳本。在 install 目錄下創建一個簡單的名為 SetupScript.iss 的腳本文件,大部分保留了默認值(懶得修改公司名之類的了),它只是將 Release 目錄的內容全部打包起來,內容如下:

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "My Program"
#define MyAppPublisher "My Company, Inc."
#define MyAppURL "https://www.example.com/"
#define MyAppExeName "wpf.exe"
#define VersionSourceAssemblyName     MyAppExeName
#define BuildOutputFolder  "..\wpf\bin\Release\"
#define MyAppFileVersion              GetFileVersion(AddBackslash(BuildOutputFolder) + VersionSourceAssemblyName)
#define MyAppCustomerVersion          GetStringFileInfo(AddBackslash(BuildOutputFolder) + VersionSourceAssemblyName, "ProductVersion")
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{0B50DAF7-728E-48C7-984F-5E6FDB924490}
AppName={#MyAppName}
AppVersion={#MyAppCustomerVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
DisableProgramGroupPage=yes
; Uncomment the following line to run in non administrative install mode (install for current user only.)
;PrivilegesRequired=lowest
OutputBaseFilename=mysetup {#MyAppCustomerVersion}
Compression=lzma
SolidCompression=yes
WizardStyle=modern

VersionInfoCompany={#MyAppPublisher}
VersionInfoVersion={#MyAppFileVersion}
VersionInfoProductName={#MyAppName}
VersionInfoProductTextVersion={#MyAppCustomerVersion}

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "{#BuildOutputFolder}{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#BuildOutputFolder}*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; 
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

用 Inno Setup 運行一下這個腳本文件確保它正確運行(如果成功的話會在 Installer\Output 目錄下生成一個安裝程序)。

3. 在 Azure Pipelines 上運行 Inno Setup

SetupScript.iss 推送到 Azure Repos 上,然后修改對應的 Pipeline。Pipeline 中需要添加兩個任務:

  • 一個負責使用 Chocolatey 下載並安裝 Inno Setup 的任務
  • 一個調用 Inno Setup 運行 SetupScript.iss 的任務

然后修改 CopyFiles 任務,將 Installer\output 目錄中的安裝包復制到 $(build.artifactstagingdirectory)。修改后的 YAML 文件如下(其中兩個 PowerShell 任務即為新增的兩個任務):

trigger:
- master
pool:
   vmImage: 'windows-latest'
variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller@1

- task: PowerShell@2
  displayName: 'Inno setup download'
  inputs:
    targetType: 'inline'
    script: 'choco install innosetup'
- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'
- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
- task: PowerShell@2
  displayName: 'Execute Inno Setup script'
  inputs:
    targetType: 'inline'
    script: 'iscc.exe Installer\\SetupScript.iss'
    
- task: CopyFiles@2
  inputs:
    SourceFolder: 'Installer\\output'
    Contents: '*.exe'
    TargetFolder: '$(build.artifactstagingdirectory)'
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

4. 最后

現在,一個桌面應用程序的 CI/CD 已經基本完成了。當然實際應用中 iss 腳本和 PowerShell 都可以更復雜以便完成更多任務,例如程序簽名、檢查並安裝 .Net Framework 等,這些操作都超出了這篇文章的范疇,如有需要可以參考下面這些鏈接:

Azure Pipelines 文檔

Inno Setup - a free installer for Windows programs

Chocolatey Software - The package manager for Windows


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM