使用WiX打包你的应用程序之二---向WiX脚本传递信息(属性)的几种方式

这个系列的第一篇文章,向大家演示了一个最简单的WiX实例.这一篇开始,作为一个逻辑上的延展,我们有义务让WiX引擎知道去哪里取得需要打包的文件. 更深入的,我们需要让WiX在编译生成的时候,动态的知道一些信息.传递动态信息的方法归结起来, 一般有2种方式: 替换法和参数法.

 

现在, 假设我们需要让WiX脚本知道, 当前生成的安装包的版本号是什么 - 这是必要的,因为最终生成的安装包的版本依赖于这个版本号. 而每次生成程序或者程序集的编译过程中所使用的版本号各不相同, 所以他是动态的. 我们看一下这个属性如何从外部传送到WiX脚本内.

 

还是拿上一篇稍稍修改的WiX脚本文件(wixdemo.wxs)做例子:

 

1. 替换法.

使用替换法,可以在每个.wxs文件的开始部分填写一个默认的属性及其值,然后在编译这个wxs文件之前,及时的替换掉默认值, 一般可以这么写:

<?xml version="1.0" encoding="utf-8"?>
<?define VERSION="%BUILDNUMBER%"?>
<?define SOURCEDIR="%SOURCEDIR%"?>
<Wix xmlns="http://schmeas.microsoft.com/wix/2003/01/wi">
    <Product Name="WixDemo" Id="904F998D-B3BE-4536-9ABE-F8B72B98BCEA" 
                Language="1033" Version="$(var.VERSION)" Manufacturer="Wix Demo Corp.">
        <Package Id="4DB93456-952B-4463-BFD0-86306D5C29D4" Keywords="Installer" 
                Description="Our road to first wix installer" Comments="We will rock you" 
                 Manufacturer="Our Corp." InstallerVersion="100" Languages="1033" 
                 Compressed="yes" SummaryCodepage="1252" />
        <Media Id="1" Cabinet="OMSimulator.cab" EmbedCab="yes" />
          <Directory Id="TARGETDIR" Name="SourceDir">
              <Directory Id="ProgramFilesFolder" Name="PFiles">
                      <!--Write a new key to registry on installation and remove it when unstallation-->
                  <Component Id="RegComponent" Guid="6EEBA57B-A0B0-4328-A414-931A14904913" DiskId="1">
                      <Registry Id="SignatureKey" Root="HKLM" 
                              Key="SOFTWARE\WixDemo\MySignature" 
                              Action="createKeyAndRemoveKeyOnUninstall" />
                  </Component>
                      <!--Target Directory: ProgramFile\Wix Demo Application-->
                  <Directory Id="WIXDEMO" Name="WixDemo" LongName="Wix Demo Application">
                          <!--File to be copied-->
                      <Component Id="WixApp" Guid="C03083B7-E539-47b3-84C6-88ED783A5C31">
                              <File Id="File_1" 
                                      Name="Readme"  
                                      LongName="Readme.txt" 
                                      KeyPath="no" 
                                      Compressed="yes" 
                                      src="$(var.SOURCEDIR)\" 
                                      DiskId="1"/>
                      </Component>
                  </Directory >
              </Directory>
        </Directory>
 
        <Feature Id="DemoFeature" Title="This feature installs the components for WiX demo" Level="1">
          <ComponentRef Id="RegComponent"/>
          <ComponentRef Id="WixApp" />
          <ComponentRef Id="Config" />
        </Feature>
      
      <Property Id="INSTANCE" Value="." />
      <Property Id="DEMODB" Value="WixDemoDB" />
    </Product>
</Wix>

 

我们在进行编译之前,需要及时的替换掉%BUILDNUMBER%和%SOURCEDIR%. 这做起来很容易,你可以写C# code来做,也可以使用别的方法. 不过如果你用的编译环境是TFS, 或者更宽泛的说,是基于MSBuild引擎或者NTBuild引擎, 那么你可以直接使用Microsoft SDC tasks library, 放心,这个task library是免费的, 而且有很多额外的奖励^_^.

 

在编译脚本里面的适当地方(在编译wix脚本之前)添加上这么几行:

<UsingTask TaskName="File.Regex" 
AssemblyFile="$(TeamBuildRefPath)\Microsoft.Sdc.Tasks.dll" />
<File.Regex Path="$(WixScriptFolder)\wixdemo.wxs" 
    RegularExpression="%BUILDNUMBER%" 
    NewValue="1.1.0.1" />
<File.Regex Path="$(WixScriptFolder)\wixdemo.wxs" 
    RegularExpression="%SOURCEDIR%" 
    NewValue="C:\BuildDir\Output" />

这里为了示例,直接使用了具体的buildnumber和输出目录, 你可以而且应该使用来自于编译环境中的有关属性变量, 比如, $(BuildNumber)等.

 

2. 传递参数法.

wix毕竟是一个引擎, 它本质上还是一个基于命令行的程序, 我们可以给这个命令行程序传递参数来实现向wix脚本传递动态属性的目的.

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schmeas.microsoft.com/wix/2003/01/wi">
    <Product Name="WixDemo" Id="904F998D-B3BE-4536-9ABE-F8B72B98BCEA" 
                Language="1033" Version="$(var.VERSION)" Manufacturer="Wix Demo Corp.">
        <Package Id="4DB93456-952B-4463-BFD0-86306D5C29D4" Keywords="Installer" 
                Description="Our road to first wix installer" Comments="We will rock you" 
                 Manufacturer="Our Corp." InstallerVersion="100" Languages="1033" 
                 Compressed="yes" SummaryCodepage="1252" />
        <Media Id="1" Cabinet="OMSimulator.cab" EmbedCab="yes" />
          <Directory Id="TARGETDIR" Name="SourceDir">
              <Directory Id="ProgramFilesFolder" Name="PFiles">
                      <!--Write a new key to registry on installation and remove it when unstallation-->
                  <Component Id="RegComponent" Guid="6EEBA57B-A0B0-4328-A414-931A14904913" DiskId="1">
                      <Registry Id="SignatureKey" Root="HKLM" 
                              Key="SOFTWARE\WixDemo\MySignature" 
                              Action="createKeyAndRemoveKeyOnUninstall" />
                  </Component>
                      <!--Target Directory: ProgramFile\Wix Demo Application-->
                  <Directory Id="WIXDEMO" Name="WixDemo" LongName="Wix Demo Application">
                          <!--File to be copied-->
                      <Component Id="WixApp" Guid="C03083B7-E539-47b3-84C6-88ED783A5C31">
                              <File Id="File_1" 
                                      Name="Readme"  
                                      LongName="Readme.txt" 
                                      KeyPath="no" 
                                      Compressed="yes" 
                                      src="$(var.SOURCEDIR)\" 
                                      DiskId="1"/>
                      </Component>
                  </Directory >
              </Directory>
        </Directory>
 
        <Feature Id="DemoFeature" Title="This feature installs the components for WiX demo" Level="1">
          <ComponentRef Id="RegComponent"/>
          <ComponentRef Id="WixApp" />
          <ComponentRef Id="Config" />
        </Feature>
      
      <Property Id="INSTANCE" Value="." />
      <Property Id="DEMODB" Value="WixDemoDB" />
    </Product>
</Wix>

上面这个脚本和第一个脚本的区别是开头去掉了默认属性, 那么我们该如何传递呢?

实际上, 只要我们在使用wix命令的时候,加上-d接这个参数就可以了:

<Exec Command="$(WixTool)\candle.exe $(WixScriptFolder)\wixdemo.wxs -dVERSION=1.1.0.1 -dSOURCEDIR=c:\BuildDir\Output /nologo"
WorkingDirectory="$(WixScriptFolder)"/>
<Exec Command="$(WixTool)\light.exe $(WixScriptFolder)\wixdemo.wixobj $(WixTool)\sca.wixlib $(WixTool)\wixca.wixlib /out wixdemo.msi /nologo"
WorkingDirectory="$(WixScriptFolder)"/>

 

总结: 传递动态属性的基本方法就是这两类. 在一些集成环境中,你可能遇到一些神出鬼没的属性, 它们最终总会归结为这两类中的一类, 比如常见的CoreXT当中的PackageTarget, 比如TFS当中的PackageBinaries Targets等.

 

需要特别注意的是,属性有公有和私有之分,所有需要传递的属性都是公有属性. 所有的公有属性都应该完全大写!

posted @ 2008-08-12 11:19  Jeffrey Sun  阅读(4976)  评论(3编辑  收藏  举报