为XNA制做安装程序(四)WIX Toolset 3.0 for Visual Studio 2008

首先到http://wix.sourceforge.net/下载最新的WIX,这是一款开源的安装程序打包工具,其中2.0版本和3.0是可以安装在VS2008下,而3.5安装在VS2010中。我们用VS2008开发XNA3.1的游戏,所以就下载3.0的版本使用,目前的版本是3.0.5419.0。

安装后会在Visual Studio 2008中的关于中显示安装版本,它也可以安装在Visual C# 2008 Express 中:

 


WIX是免费开源的安装工具,有很多的版本和很高的声誉。可惜依然有一些不足,比如对中文的支持程度,中文文档和教程匮乏,没有UI界面配置,需要使用命令行进行编译,文件输入的繁琐,默认没有XML智能提示等等。虽然目前支持Visual Studio 2008,但是对SharpDevelop支持得更好一些。想要说明白整个WIX的原理和参数设置以及演示,哪怕是最基本的,我想一篇文章都很难写出来,所以这里只简单看一下环境,基本设置,使用已经成形的WIX脚本,修改一些参数,生成我们自己的安装程序,最后解释一些设置。

1,建立项目:

首先在解决方案管理器上右键单击“添加”->“新建项目”->左侧选“WiX”,右侧选择“WiX Project”,然后起个名字,这里叫JewelsWixSetup,选择项目位置,然后“确定”。

2009111301

然后在项目列表中可以看到这个项目,默认建立后只有一个文件Product.wxs,这是一个XML格式的文件,不进行任何改动,在项目名称上右键点击生成,可以在输出窗口看到:

------ 已启动生成: 项目: JewelsWixSetup, 配置: Release x86 ------
        D:\Program Files (x86)\Windows Installer XML v3\bin\candle.exe -d"DevEnvDir=D:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\\" -dSolutionDir=C:\Users\han\Desktop\jewels-v1.0-src\ -dSolutionExt=.sln -dSolutionFileName=Jewels.sln -dSolutionName=Jewels -dSolutionPath=C:\Users\han\Desktop\jewels-v1.0-src\Jewels.sln -dConfiguration=Release -dOutDir=bin\Release\ -dPlatform=x86 -dProjectDir=C:\Users\han\Desktop\JewelsWixSetup\ -dProjectExt=.wixproj -dProjectFileName=JewelsWixSetup.wixproj -dProjectName=JewelsWixSetup -dProjectPath=C:\Users\han\Desktop\JewelsWixSetup\JewelsWixSetup.wixproj -dTargetDir=C:\Users\han\Desktop\JewelsWixSetup\bin\Release\ -dTargetExt=.msi -dTargetFileName=JewelsWixSetup.msi -dTargetName=JewelsWixSetup -dTargetPath=C:\Users\han\Desktop\JewelsWixSetup\bin\Release\JewelsWixSetup.msi -out obj\Release\Product.wixobj -arch x86 Product.wxs
        D:\Program Files (x86)\Windows Installer XML v3\bin\Light.exe -cultures:null -out C:\Users\han\Desktop\JewelsWixSetup\bin\Release\JewelsWixSetup.msi -pdbout C:\Users\han\Desktop\JewelsWixSetup\bin\Release\JewelsWixSetup.wixpdb obj\Release\Product.wixobj
C:\Users\han\Desktop\JewelsWixSetup\Product.wxs(6,0): warning LGHT1079: The cabinet 'media1.cab' does not contain any files.  If this installation contains no files, this warning can likely be safely ignored.  Otherwise, please add files to the cabinet or remove it.
========== 生成: 成功或最新 1 个,失败 0 个,跳过 0 个 ==========

 

 

 

2,下载并更新项目文件

本来应该在命令行下执行的candle.exe和light.exe现在由编译器代为执行。这里消息栏会提示警告,提示我们的项目中不包含任何文件,向这里面添加文件异常麻烦,如果没有工具就只能手工修改XML文件内容。目前有一个半开源的工具可以使用,算是相对较好的解决方案,WiX XNA Installer,这是一款用于SharpDevelop3.0的项目,可以检测客户机的.NET、XNA、DirectX 9.0c、Sharder Model版本。安装包可选择是否内置XNA3.1的可再发行组件包,但无法选择内置.NET组件包。这也可以理解,国外的Win7相对普及,一般不会担心是否没有.NET组件包的情况,只能做检测,然后提示用户到官网上去下载。

本文写出来的时候这个项目的版本是3.1.7-beta,发布于2009年8月21日,你可以下载当前最新的版本。下载后解压后不要打开项目文件,会提示不支持,因为那不是Visual Studio的文件类型。将其中的5个文件夹(Content,Documents,References,Resources,Source)复制到JewelsWixSetup项目根目录下,MyGame.sln,MyGame.wixproj,Open With SharpDevelop!三个文件不要理会。

在解决方案管理器中选择JewelsWixSetup,然后点击显示所有文件,将这5个目录依次包括到项目中,再把项目根目录中的Product.wxs删除。

3,修改项目文件内容并测试安装程序

依次找到四个字符串:“!replace-this-with-real-product_guid”,“!replace-this-with-real-upgrade_guid”,“!replace-this-with-game-component_id”,“!replace-this-with-menu-component_id”,用四个随机GUID代替。可以使用Visual Studio自带的GUID生成器,在“工具”->“创建 GUID”。选择第四项:Registry Format,依次点击NEW GUID生成并复制到以上四个位置。(分别在Files.wxs和Setup.wxs中)

这个项目预制了很多安装界面,需要引用项目图片,这些项目图片存放在Jewels项目中的installer目录中:installer_header.bmp,installer_title.bmp等。现在我们要在新建的JewelsWixSetup项目中引用Jewels项目中的这几张图片,步骤如下:1,在JewelsWixSetup中的References上右键,添加引用,在弹出的对话框中选择Jewels项目,点击添加,然后确定引用:

2009111302

然后打开Source/UserInterface.wxs文件,找到如下内容:

<!--
  Default dialog resources for the setup
-->
<Binary Id="dialog.bmp" SourceFile="$(var.DATADIR)/default-dialog.bmp" />
<Binary Id="banner.bmp" SourceFile="$(var.DATADIR)/default-banner.bmp" />
<Binary Id="info.bmp" SourceFile="$(var.DATADIR)/info.bmp" />
<Binary Id="up.bmp" SourceFile="$(var.DATADIR)/up.bmp" />
<Binary Id="new.bmp" SourceFile="$(var.DATADIR)/new.bmp" />

将它替换为:

<Binary Id="dialog.bmp" SourceFile="$(var.Jewels.TargetDir)installer\installer_header.bmp" />
<Binary Id="banner.bmp" SourceFile="$(var.Jewels.TargetDir)installer\installer_header.bmp" />
<Binary Id="info.bmp" SourceFile="$(var.Jewels.TargetDir)installer\installer_title.bmp" />
<Binary Id="up.bmp" SourceFile="$(var.Jewels.TargetDir)installer\installer_header.bmp" />
<Binary Id="new.bmp" SourceFile="$(var.Jewels.TargetDir)installer\installer_header.bmp" />

$(var.Jewels.TargetDir是Wix内置变量,TargetDir是项目的编译生成的目标目录,其它的内置变量请看这里

保存后生成JewelsWixSetup项目,在C:\Users\han\Desktop\JewelsWixSetup\bin\Release里找到JewelsWixSetup.msi,在本机安装这个项目,如果在程序菜单中的“MyGame”目录下有一个“MyGame Shortcut”快捷方式,点击后显示一个“Game Placeholder”对话框显示”You launched the example game!”,就说明我们的安装程序制做成功了。最后检查注册表键,在HKCU\SOFTWARE\MyCompany\MyGame下应该有一个Hello world的键值。

4,订制安装程序

检测参数文件:Config.wxi

InstallPrerequisitesIfRequired:如果客户机没有安装.NET Framework 2.0 SP1, DirectX 9.0c for XNA 2.0 and XNA 2.0等,是否需要检测这些组件安装才能使用。
RequiredShaderModel:需要的Shader model版本,如果低于这个版本,用户安装时会出现警告:


RequiredDotNetVersion:需要的.NET版本,如果连.net2.0都没有的话,用户安装会出现:


安装配置文件:Setup.wxs

在Product节中,Name就是安装文件夹的名称,这里改成Jewels;Language指语言符号,1033是en-us(美国-英语),2052是zh-cn(简体-中文),1028是zh-tw(繁体-中文),Version是文件版本,Manufacturer是公司名或程序作者名,这里改成Omgsoft。

Package节中是安装包的信息,参考http://wix.sourceforge.net/manual-wix2/wix_xsd_package.htm,根据实际需要自行修改。

在JewelsWixSetup项目下的Source/Dialogs中是一些对话框的定义,你可以对照显示英文在这里搜索相应的窗口,再改成中文。

在Files.wxs中,修改MyGameProgramMenuFolder目录属性的名称为Omgsoft,以及INSTALLDIR目录的名称为Omgsoft,将快捷方式MyGame Shortcut的名称改为Jewels

5,加入文件

最后就是所需要的具体打包文件了,手动添加十分繁琐,WiX也没有图形化的工具,只有一个heat.exe可以使用,具体使用方法参考,直接编译Jewels所有项目文件,在命令行下输入:

D:
cd D:\Program Files (x86)\Windows Installer XML v3\bin\
D:\Program Files (x86)\Windows Installer XML v3\bin>heat.exe project C:\Users\han\Desktop\jewels-v1.0-src\Jewels.csproj -pog:Binaries -ag -template:fragment -out C:\Users\han\Desktop\JewelsWixSetup\Source\JewelsFiles1.wxs
Microsoft (R) Windows Installer Xml Toolset Harvester version 3.0.5419.0
Copyright (C) Microsoft Corporation. All rights reserved.

但是这种方法不能识别XNA特有的xnb文件格式,如果用整个目标编译的方式的话,生成的文件会把每一个文件file作为一个component节来处理,那样我们还要为每个component在Feature中进行一次声明,这样并不能减少工作量,所以还是手动添加。

回到Files.wxs中,找到ID为INSTALLDIR的Directory节,加入自己的文件,所有的file节必须在component节中,新建立的component必须在setup.wxs中的feature中进行注册。文件里给了如何引用文件和建立快捷方式的例子,先将例子中主程序文件的Source属性改为$(var.Jewels.TargetDir)/Jewels.exe,再加入Content目录:

<Directory Id="INSTALLDIR" Name="MyGame">
  <Directory Id="ContentDir" Name="Content">
  </Directory>
</Directory>

新增加的文件外侧至少需要一个Component节,另再加一个声音的目录,看起来会是这样:

<Directory Id="INSTALLDIR" Name="Jewels">
  <Directory Id="ContentDir" Name="Content">
    <Component Id="TextureComponent" Guid="<some guid>" DiskId="1">
      <File Id="bground1" Name="bground1.xnb" Source=”$(var.Jewels.TargetDir)/Content/bground1.xnb" />
      <File Id="bground2" Name="bground2.xnb" Source=”$(var.Jewels.TargetDir)/Content/bground2.xnb" />
      <File Id="bground3" Name="bground3.xnb" Source=”$(var.Jewels.TargetDir)/Content/bground3.xnb" />
      <File Id="bground4" Name="bground4.xnb" Source=”$(var.Jewels.TargetDir)/Content/bground4.xnb" />
      <File Id="bigfont" Name="bigfont.xnb" Source=”$(var.Jewels.TargetDir)/Content/bigfont.xnb" />
      <File Id="BloomCombine" Name="BloomCombine.xnb" Source=”$(var.Jewels.TargetDir)/Content/BloomCombine.xnb" />
      <File Id="BloomExtract" Name="BloomExtract.xnb" Source=”$(var.Jewels.TargetDir)/Content/BloomExtract.xnb" />
      <File Id="board" Name="board.xnb" Source=”$(var.Jewels.TargetDir)/Content/board.xnb" />
      <File Id="bonusbar" Name="bonusbar.xnb" Source=”$(var.Jewels.TargetDir)/Content/bonusbar.xnb" />
      <File Id="borders" Name="borders.xnb" Source=”$(var.Jewels.TargetDir)/Content/borders.xnb" />
      <File Id="borders_hilight" Name="borders_hilight.xnb" Source=”$(var.Jewels.TargetDir)/Content/borders_hilight.xnb" />
      <File Id="credits" Name="credits.xnb" Source=”$(var.Jewels.TargetDir)/Content/credits.xnb" />
      <File Id="creditsbump" Name="creditsbump.xnb" Source=”$(var.Jewels.TargetDir)/Content/creditsbump.xnb" />
      <File Id="fill" Name="fill.xnb" Source=”$(var.Jewels.TargetDir)/Content/fill.xnb" />
      <File Id="fpsfont" Name="fpsfont.xnb" Source=”$(var.Jewels.TargetDir)/Content/fpsfont.xnb" />
      <File Id="GaussianBlur" Name="GaussianBlur.xnb" Source=”$(var.Jewels.TargetDir)/Content/GaussianBlur.xnb" />
      <File Id="islands" Name="islands.xnb" Source=”$(var.Jewels.TargetDir)/Content/islands.xnb" />
      <File Id="jewels" Name="jewels.xnb" Source=”$(var.Jewels.TargetDir)/Content/jewels.xnb" />
      <File Id="jewels_flash" Name="jewels_flash.xnb" Source=”$(var.Jewels.TargetDir)/Content/jewels_flash.xnb" />
      <File Id="jewels_hilight" Name="jewels_hilight.xnb" Source=”$(var.Jewels.TargetDir)/Content/jewels_hilight.xnb" />
      <File Id="logo" Name="logo.xnb" Source=”$(var.Jewels.TargetDir)/Content/logo.xnb" />
      <File Id="mhgames" Name="mhgames.xnb" Source="$(var.Jewels.TargetDir)/Content/mhgames.xnb" />
      <File Id="monofont" Name="monofont.xnb" Source=”$(var.Jewels.TargetDir)/Content/monofont.xnb" />
      <File Id="mouse" Name="mouse.xnb" Source=”$(var.Jewels.TargetDir)/Content/mouse.xnb" />
      <File Id="normalfont" Name="normalfont.xnb" Source=”$(var.Jewels.TargetDir)/Content/normalfont.xnb" />
      <File Id="options" Name="options.xnb" Source=”$(var.Jewels.TargetDir)/Content/options.xnb" />
      <File Id="particles" Name="particles.xnb" Source=”$(var.Jewels.TargetDir)/Content/particles.xnb" />
      <File Id="scorefont" Name="scorefont.xnb" Source=”$(var.Jewels.TargetDir)/Content/scorefont.xnb" />
      <File Id="selection" Name="selection.xnb" Source=”$(var.Jewels.TargetDir)/Content/selection.xnb" />
      <File Id="small_scorefont" Name="small_scorefont.xnb" Source=”$(var.Jewels.TargetDir)/Content/small_scorefont.xnb" />
      <File Id="smallfont" Name="smallfont.xnb" Source=”$(var.Jewels.TargetDir)/Content/smallfont.xnb" />
      <File Id="water" Name="water.xnb" Source=”$(var.Jewels.TargetDir)/Content/water.xnb" />
      <File Id="waterbump" Name="waterbump.xnb" Source=”$(var.Jewels.TargetDir)/Content/waterbump.xnb" />
    </Component>
    <Directory Id="AudioDir" Name="Audio">
      <Component Id="AudioComponent" Guid="<some guid>" DiskId="1">
        <File Id="jewels.xgs" Name="jewels.xgs" Source=”$(var.Jewels.TargetDir)/Content/Audio/jewels.xgs" />
        <File Id="SoundBank.xsb" Name="SoundBank.xsb" Source=”$(var.Jewels.TargetDir)/Content/Audio/SoundBank.xsb" />
        <File Id="WaveBank.xwb" Name="WaveBank.xwb" Source=”$(var.Jewels.TargetDir)/Content/Audio/WaveBank.xwb" />
      </Component>
    </Directory>
  </Directory>
</Directory>

然后在Setup.wxs的Feature节中注册组件,增加引用:

<ComponentRef Id="TextureComponent"/>
<ComponentRef Id="AudioComponent"/>

最后生成JewelsWixSetup这个项目,到Release目录中取出JewelsWixSetup.msi,双击,开始界面之后是许可协议,然后是组件检测,选择安装位置,安装。

2009111401

安装顺利,正常运行,再到XP系统下,因为这个安装包并不内置.NET组件,所以我预装了.NET2.0,检测到DX9和XNA都没有:

2009111402

点击安装就会自动安装所需要的组件而无须再上网下载,之后就是选择目录,安装。

对于有.NET2.0的Win7和Vista用户来说,这种安装方式非常实用,自身包含了DX9和XNA3.1,不过是增加了6M左右的容量,对于一般游戏来说都可以忽略不计。缺点是设置比较繁琐,对于以上的例子,还有很多地方需要中文化,亦需要大量时间精力。

需要测试的朋友可以到这里下载本文所打好包的游戏安装包。 

希望本文能对您有所帮助。

未完待续。

posted @ 2009-11-14 20:48  风海迷沙  阅读(4151)  评论(1编辑  收藏  举报