65.9K
CodeProject 正在变化。 阅读更多。
Home

快速入门:使用 WiX 创建 MSI 安装程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.58/5 (28投票s)

2010年8月30日

CPOL

6分钟阅读

viewsIcon

367672

这篇快速入门面向希望使用免费的 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.msiexample_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 安装程序,您可能希望添加更多文件和图形界面。以下是查找更多信息的地方:大多数功能可以通过向 XML 文件添加更多信息和更改批处理文件的参数来实现。

故障排除

  • 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 部分(主版本.次版本.构建版本),否则软件升级将无法正常工作

外部链接

© . All rights reserved.