自動化建置與部署是現代軟體工程的基石。本文詳細介紹如何結合 Windows Installer XML (WiX) 與 MSBuild,建立可重複、可靠的自動化打包流程,涵蓋 WiX 基礎、MSBuild 批次處理、完整建置腳本架構與自定義擴展。
WiX 使用宣告式 XML 描述安裝程式外觀與行為,核心三要素:
主要工具鏈:
| 工具 | 功能 |
|---|---|
| Candle.exe | 編譯 .wxs 為中間 .wixobj |
| Light.exe | 連結 .wixobj 產出 .msi |
| Lit.exe | 建立 WiX 函式庫 |
| Tallow.exe | 掃描目錄產生檔案/資料夾 XML |
<?xml version='1.0' encoding='UTF-8'?>
<Wix xmlns='https://schemas.microsoft.com/wix/2003/01/wi'>
<Product Name='Sedodream MSBuild Project'
Id='C9D25926-FCE0-4EB6-8FF5-4686EE5AB089'
Version='1.0.0' Manufacturer='SedoTech'
UpgradeCode='9C5E4073-EFDE-419B-935D-CE2632BC560E'>
<Package Id='*' Keywords='Installer' Description='...' Compressed='yes' />
<Media Id='1' Cabinet='Sedodream.cab' EmbedCab='yes'/>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder'>
<Directory Id='MSBuildDir' Name='MSBuild'>
<Directory Id='INSTALLDIR' Name='Sedodream' LongName='Sedodream'>
</Directory>
</Directory>
</Directory>
</Directory>
<Component Id='TaskBinFiles' Guid='38736E2E-BEB7-48A9-A2B3-138A57A69D45'>
<File Id='MSBCommonDLL' Source='Sedodream.MSBuild.Common.dll' Vital='yes' DiskId='1'/>
<File Id='SedodreamLoggersDLL' Source='Sedodream.MSBuild.Loggers.dll' Vital='yes' DiskId='1'/>
<!-- 修改 VS xsd 啟用 IntelliSense -->
<XmlFile Id='SedoSche' Action='createElement' ... />
<XmlFile Id='SedoSch2' Action='setValue' ... />
</Component>
<Feature Id='Complete' Title='Sedodream Core' Level='1' ConfigurableDirectory='INSTALLDIR'>
<ComponentRef Id='TaskBinFiles'/>
<Feature Id='Samples' Title='Samples' Level='100'>
<ComponentRef Id='Samples'/>
</Feature>
</Feature>
</Product>
</Wix>
WiX 提供 wix.targets 內建 MSBuild 任務:Candle、Light、Lit。專案檔僅需宣告屬性與項目:
<Project DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ToolPath>C:\Data\Development\WiX\</ToolPath>
<OutputName>$(Configuration)Sedodream</OutputName>
<OutputType>package</OutputType>
<BaseInputPath>$(PackageRoot)$(Configuration)</BaseInputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(BaseInputPath)\Sedodream.wxs"/>
</ItemGroup>
<Import Project="$(ToolPath)wix.targets"/>
</Project>
執行 msbuild Sedodream.wproj 即產出 ReleaseSedodream.msi。
MSBuild 無迴圈構造,透過批次處理實現多組態迭代。兩種模式:
Inputs/Outputs 中繼資料重複執行<!-- 目標批次範例:為每個組態產出安裝程式 -->
<Target Name="CoreBuild"
Inputs="%(AllConfigurations.PlatformToBuild);%(AllConfigurations.FlavorToBuild)"
Outputs="%(AllConfigurations.PlatformToBuild);%(AllConfigurations.FlavorToBuild)">
<MSBuild Projects="@(SolutionFile)" Targets="Build"
Properties="OutputPath=$(PackageRoot)%(AllConfigurations.FlavorToBuild);
Configuration=%(AllConfigurations.FlavorToBuild);
Platform=%(AllConfigurations.PlatformToBuild)">
<Output ItemName="OutputFiles" TaskParameter="TargetOutputs"/>
</MSBuild>
</Target>

| 目標 | 職責 |
|---|---|
| Package | 總入口,串聯所有子目標 |
| Build | 建置方案檔,輸出導向 PackageRoot |
| CopyFilesForPackaging | 複製非建置產出檔(授權、位圖、範例等) |
| DeployPackage | 部署至 QA/生產環境(專案自行實作) |
| Clean | 清理暫存檔 |
透過重新定義 BuildDependsOn 注入自訂步驟:
<BuildDependsOn>CustomBeforeBuild; $(BuildDependsOn);</BuildDependsOn>
<Project DefaultTargets="Package">
<PropertyGroup>
<SolutionFilePath>..\Sedodream.MSBuild.sln</SolutionFilePath>
<PackageRoot>..\Package\</PackageRoot>
<DropLocation>C:\Data\Drops\MSBuild-Wix\</DropLocation>
</PropertyGroup>
<ItemGroup>
<WiXSourceFiles Include="Sedodream.wxs"/>
<OtherFiles Include="..\Sedodream.MSBuild.Tasks\SampleTargets\**\*">
<Destination>Samples\</Destination>
</OtherFiles>
<OtherFiles Include="License.rtf"><Destination></Destination></OtherFiles>
<OtherFiles Include="bitmaps\dlgbmp.bmp"><Destination>bitmaps\</Destination></OtherFiles>
</ItemGroup>
<ItemGroup>
<AllConfigurations Include="Debug|x86">
<FlavorToBuild>Debug</FlavorToBuild>
<PlatformToBuild>Any CPU</PlatformToBuild>
</AllConfigurations>
<AllConfigurations Include="Release|Any CPU">
<FlavorToBuild>Release</FlavorToBuild>
<PlatformToBuild>Any CPU</PlatformToBuild>
</AllConfigurations>
</ItemGroup>
<Import Project="Sedodream.Package.targets"/>
</Project>
TFSBuild.proj 中呼叫 MSBuild 任務msbuild.exe Package.dprojWiX + MSBuild 提供強大、標準化的自動化打包基礎。核心在於:宣告式 WiX 源檔、MSBuild 批次處理多組態、共用 .targets 封裝流程邏輯、專案檔僅宣告資料。一旦建立,即可持續交付高品質安裝程式。