快速入门:使用 WiX 创建 MSI 安装程序
这篇快速入门面向希望使用免费的 WiX 工具集 v3.0 创建简单 MSI 安装程序的开发人员。
入门
首先,您需要准备以下内容1) 在 Windows XP 上,如果您尚未安装 Microsoft .NET Framework,则可能需要下载并安装它。WiX 工具集需要 .NET Framework,目前是 3.5 SP1 版本。安装过程需要一些时间,您可以趁此机会去喝杯咖啡。
2) 下载并安装以下文件:WiX Toolset v3.0。WiX 是一套免费工具,用于根据 XML 文档构建软件安装程序。
您可以从命令行构建安装程序,也可以使用 Visual Studio 或 Eclipse 等 IDE。下面我们来看一下这些工具,并从命令行创建一个 MSI 文件。
创建您的第一个 WiX 文件
创建一个名为example.wxs
的 XML 文件,内容如下:<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
</Wix>
这是最基本的配置,我们再稍微添加一些内容<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1234-1234-1234-111111111111"
Name="Example Product Name" Version="0.0.1" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222"/>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
</Feature>
</Product>
</Wix>
创建您的第一个 MSI 安装程序
创建一个名为make_installer.bat
的批处理文件,内容如下:candle example.wxs
light example.wixobj
@pause
运行它来构建包,忽略任何警告。如果您好奇的话:candle
是 WiX 编译器(生成目标文件),light
是 WiX 链接器(生成最终的安装程序)。现在您的文件夹中应该有一个 example.msi
文件,恭喜您!双击它进行安装,然后在控制面板的“添加/删除程序”中,您会找到一个名为“Example Product Name
”的条目。别忘了卸载它,以便之后您可以构建和安装新的 MSI 文件。创建一个简单的应用程序安装程序
将一个应用程序复制到与您的example.wxs
相同的目录中,任何独立的可执行文件都可以(例如,如果您没有其他可用程序,可以使用 C:\WINDOWS\system32\notepad.exe
)。将应用程序重命名为 example.exe
。修改您的 XML 文件 example.wxs
中的以下行:<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1234-1234-1234-111111111111"
Name="Example Product Name" Version="0.0.1" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
</Feature>
</Product>
</Wix>
再次运行 make_installer.bat
来构建包,然后双击 example.msi
进行安装。这次,您的“程序文件”文件夹中会有一个名为 Example
的目录,并且 example.exe
将安装在那里。您可以通过控制面板的“添加/删除程序”来卸载您的应用程序,或者右键单击 MSI 文件并选择“卸载”。创建开始菜单项
这会将您的示例应用程序添加到开始菜单。由于开始菜单项是一个快捷方式而不是一个实际文件,因此需要一个注册表项。修改您的 XML 文件example.wxs
中的以下行:<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1234-1234-1234-111111111111"
Name="Example Product Name" Version="0.0.1" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuSubfolder" Name="Example">
<Component Id="ApplicationShortcuts" Guid="12345678-1234-1234-1234-333333333333">
<Shortcut Id="ApplicationShortcut1" Name="Example Shortcut Name" Description="Example Product Name"
Target="[INSTALLDIR]example.exe" WorkingDirectory="INSTALLDIR"/>
<RegistryValue Root="HKCU" Key="Software\Example Company Name\Example Product Name"
Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<RemoveFolder Id="ProgramMenuSubfolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
<ComponentRef Id="ApplicationShortcuts"/>
</Feature>
</Product>
</Wix>
再次运行 make_installer.bat
,进行测试并卸载您的 example.msi
。如何进行软件升级
软件升级需要一些配置,因为有些值会重复使用,所以我们将其定义为变量。修改您的 XML 文件example.wxs
中的以下行:<?xml version="1.0"?>
<?define ProductVersion = "0.0.1"?>
<?define ProductUpgradeCode = "12345678-1234-1234-1234-111111111111"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)"
Name="Example Product Name" Version="$(var.ProductVersion)" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
<UpgradeVersion Minimum="0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="no"
Property="OLDERVERSIONBEINGUPGRADED"/>
</Upgrade>
<Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuSubfolder" Name="Example">
<Component Id="ApplicationShortcuts" Guid="12345678-1234-1234-1234-333333333333">
<Shortcut Id="ApplicationShortcut1" Name="Example Shortcut Name" Description="Example Product Name"
Target="[INSTALLDIR]example.exe" WorkingDirectory="INSTALLDIR"/>
<RegistryValue Root="HKCU" Key="Software\Example Company Name\Example Product Name"
Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<RemoveFolder Id="ProgramMenuSubfolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
<ComponentRef Id="ApplicationShortcuts"/>
</Feature>
</Product>
</Wix>
软件升级有两个重要点:在每个新版本中都要增加 ProductVersion,而 UpgradeCode 在所有版本中必须保持不变!再次运行 make_installer.bat
,构建两个具有不同 ProductVersion 号的包,并将它们命名为 example_001.msi
和 example_002.msi
。安装程序会检查是否已安装旧版本并替换它;如果已安装新版本,则会中止并显示错误消息。最后的润色
让我们添加图标和支持信息的链接,这些信息会在控制面板的“添加/删除程序”中显示。将一个图标复制到与您的example.wxs
相同的目录中,任何以 ico 结尾的图形文件都可以(例如,如果您没有其他可用图标,可以使用 https://codeproject.org.cn/favicon.ico)。将文件重命名为 example.ico
。修改您的 XML 文件 example.wxs
中的以下行:<?xml version="1.0"?>
<?define ProductVersion = "0.0.1"?>
<?define ProductUpgradeCode = "12345678-1234-1234-1234-111111111111"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)"
Name="Example Product Name" Version="$(var.ProductVersion)" Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Icon Id="ProductIcon" SourceFile="example.ico"/>
<Property Id="ARPPRODUCTICON" Value="ProductIcon"/>
<Property Id="ARPHELPLINK" Value="http://www.exampleproduct.com"/>
<Property Id="ARPURLINFOABOUT" Value="http://www.examplecompany.com"/>
<Property Id="ARPNOREPAIR" Value="1"/>
<Property Id="ARPNOMODIFY" Value="1"/>
<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
<UpgradeVersion Minimum="0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="no"
Property="OLDERVERSIONBEINGUPGRADED"/>
</Upgrade>
<Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuSubfolder" Name="Example">
<Component Id="ApplicationShortcuts" Guid="12345678-1234-1234-1234-333333333333">
<Shortcut Id="ApplicationShortcut1" Name="Example Shortcut Name" Description="Example Product Name"
Target="[INSTALLDIR]example.exe" WorkingDirectory="INSTALLDIR"/>
<RegistryValue Root="HKCU" Key="Software\Example Company Name\Example Product Name"
Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<RemoveFolder Id="ProgramMenuSubfolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
<ComponentRef Id="ApplicationShortcuts"/>
</Feature>
</Product>
</Wix>
下载最终的 WiX 安装程序示例。请记住在您的最终安装程序中将以“12345678-1234-1234-1234
”开头的所有文本替换为唯一的 GUID。同时检查所有文本“example”出现的地方,并将其替换为您的产品/公司名称。好了,就这些了。您现在已经了解了基础知识,可以开始制作自己的 MSI 安装程序了!:)
查找更多信息
一旦您熟悉了简单的 MSI 安装程序,您可能希望添加更多文件和图形界面。以下是查找更多信息的地方:- WiX 教程 - Windows Installer XML 工具集简介
- WiX - WixUI 对话库
- 又一个 WiX 教程 - 第二部分 - 添加 UI
- 在 WiX 3 中添加和自定义对话框
- Windows Installer - 自定义操作教程
- 自定义操作和卸载
- SourceForge 上的 WiX 用户邮件列表
故障排除
- WiX 命令行工具崩溃并出现以下错误:应用程序未能正确初始化 (0xc0000135)?
这是 Windows XP 上的一个已知问题,您需要安装 Microsoft .NET Framework,请参阅上面的“入门”部分。 - WiX 命令行工具出现以下错误:'program' 不是内部或外部命令,也不是可运行的程序或批处理文件?
您需要更新 PATH 环境变量,手动添加 WiX 二进制文件路径,请参阅 如何在 Windows 2000/Windows XP 中设置 PATH。英文版 Windows XP 的默认路径是C:\Program Files\Windows Installer XML v3\bin
...您可以在 Windows 资源管理器中找到您电脑上的正确路径,搜索文件candle.exe
(WiX 编译器的名称)。 - WiX 命令行工具出现 CNDL0104 错误:无效的源文件?
请确保您的 XML 文件有效。使用 XML 编辑器,或者为了快速检查,在 Firefox 中打开文件,它会以红色显示 XML 解析错误。 - 安装或更新 .NET Framework 耗时过长?
是的,最好再喝杯咖啡。还会有一到多次重启,您将花费大量等待时间。 - .NET Framework 在未经许可的情况下安装了 Firefox 扩展,如何摆脱它?
最简单的方法是打开 Firefox 菜单“工具”->“附加组件”->“Microsoft .NET Framework Assistant”,然后点击“禁用”。这不会卸载它,有关如何完全删除它的详细信息,请参阅 KB963707。 - 我的示例 MSI 文件无法安装,什么也没有发生,我该怎么办?
MSI 文件需要管理员权限,请确保您以管理员身份安装 MSI 示例。 - 网上的一些 WiX 教程不起作用,为什么?
WiX 有不同的版本,当前版本是 WiX v3.0(撰写本文时)。如果教程和博客信息相互矛盾,那是因为它们没有标明使用了哪个版本的 WiX。例如,v2.0 已过时,而 v3.5 计划中包含您尚不能使用的新功能。 - 如何为我的安装程序生成 GUID?
有命令行工具可用,或者可以在 线上创建 GUID。您至少需要一个用于 UpgradeCode,以及 XML 文件中每个组件一个。
结论
优点- 使用免费工具编写 Windows 安装程序(WiX 是开源的)
- WiX 配置可以在任何 XML 或文本编辑器中完成
- 轻松集成到自动化构建脚本中
- 可以创建多语言安装包(通过 未公开的 MSI 技巧)
- 活跃的 邮件列表 提供支持
- GUI 定制困难,默认模板通常不够用
- WiX v3.0 中的本地化不完整,例如没有瑞典语、丹麦语、挪威语、芬兰语(根据 WiX 本地化项目)
- 文档已过时且不完整,您需要搜索各种博客
- 底层的 MSI 安装程序概念复杂且学习耗时,MSI 不是一个简单的包管理器
- 文件系统和注册表清理并不容易,卸载/升级时通常需要编写自定义操作
- 软件版本限制为 3 部分(主版本.次版本.构建版本),否则软件升级将无法正常工作
外部链接
- CodePlex 上的 WiX 项目页面
- WiX Wikipedia 文章,Windows Installer XML
- MSI Wikipedia 文章,以前称为 Microsoft Installer
- NSIS Wikipedia 文章,Nullsoft 的替代 Windows 安装程序