我们已经使用WiX有一段时间了,尽管人们对它的易用性有一些抱怨,但它运行得相当不错。我想要的是有用的建议:
设置WiX项目(布局、引用、文件模式) 将WiX集成到解决方案中,并构建/发布流程 为新的安装和升级配置安装程序 任何你想分享的好的WiX技巧
我们已经使用WiX有一段时间了,尽管人们对它的易用性有一些抱怨,但它运行得相当不错。我想要的是有用的建议:
设置WiX项目(布局、引用、文件模式) 将WiX集成到解决方案中,并构建/发布流程 为新的安装和升级配置安装程序 任何你想分享的好的WiX技巧
当前回答
Keep variables in a separate wxi include file. Enables re-use, variables are faster to find and (if needed) allows for easier manipulation by an external tool. Define Platform variables for x86 and x64 builds <!-- Product name as you want it to appear in Add/Remove Programs--> <?if $(var.Platform) = x64 ?> <?define ProductName = "Product Name (64 bit)" ?> <?define Win64 = "yes" ?> <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?> <?else ?> <?define ProductName = "Product Name" ?> <?define Win64 = "no" ?> <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?> <?endif ?> Store the installation location in the registry, enabling upgrades to find the correct location. For example, if a user sets custom install directory. <Property Id="INSTALLLOCATION"> <RegistrySearch Id="RegistrySearch" Type="raw" Root="HKLM" Win64="$(var.Win64)" Key="Software\Company\Product" Name="InstallLocation" /> </Property> Note: WiX guru Rob Mensching has posted an excellent blog entry which goes into more detail and fixes an edge case when properties are set from the command line. Examples using 1. 2. and 3. <?include $(sys.CURRENTDIR)\Config.wxi?> <Product ... > <Package InstallerVersion="200" InstallPrivileges="elevated" InstallScope="perMachine" Platform="$(var.Platform)" Compressed="yes" Description="$(var.ProductName)" /> and <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="$(var.PlatformProgramFilesFolder)"> <Directory Id="INSTALLLOCATION" Name="$(var.InstallName)"> The simplest approach is always do major upgrades, since it allows both new installs and upgrades in the single MSI. UpgradeCode is fixed to a unique Guid and will never change, unless we don't want to upgrade existing product. Note: In WiX 3.5 there is a new MajorUpgrade element which makes life even easier! Creating an icon in Add/Remove Programs <Icon Id="Company.ico" SourceFile="..\Tools\Company\Images\Company.ico" /> <Property Id="ARPPRODUCTICON" Value="Company.ico" /> <Property Id="ARPHELPLINK" Value="http://www.example.com/" /> On release builds we version our installers, copying the msi file to a deployment directory. An example of this using a wixproj target called from AfterBuild target: <Target Name="CopyToDeploy" Condition="'$(Configuration)' == 'Release'"> <!-- Note we append AssemblyFileVersion, changing MSI file name only works with Major Upgrades --> <Copy SourceFiles="$(OutputPath)$(OutputName).msi" DestinationFiles="..\Deploy\Setup\$(OutputName) $(AssemblyFileVersion)_$(Platform).msi" /> </Target> Use heat to harvest files with wildcard (*) Guid. Useful if you want to reuse WXS files across multiple projects (see my answer on multiple versions of the same product). For example, this batch file automatically harvests RoboHelp output. @echo off robocopy ..\WebHelp "%TEMP%\WebHelpTemp\WebHelp" /E /NP /PURGE /XD .svn "%WIX%bin\heat" dir "%TEMP%\WebHelp" -nologo -sfrag -suid -ag -srd -dir WebHelp -out WebHelp.wxs -cg WebHelpComponent -dr INSTALLLOCATION -var var.WebDeploySourceDir There's a bit going on, robocopy is stripping out Subversion working copy metadata before harvesting; the -dr root directory reference is set to our installation location rather than default TARGETDIR; -var is used to create a variable to specify the source directory (web deployment output). Easy way to include the product version in the welcome dialog title by using Strings.wxl for localization. (Credit: saschabeaumont. Added as this great tip is hidden in a comment) <WixLocalization Culture="en-US" xmlns="http://schemas.microsoft.com/wix/2006/localization"> <String Id="WelcomeDlgTitle">{\WixUI_Font_Bigger}Welcome to the [ProductName] [ProductVersion] Setup Wizard</String> </WixLocalization> Save yourself some pain and follow Wim Coehen's advice of one component per file. This also allows you to leave out (or wild-card *) the component GUID. Rob Mensching has a neat way to quickly track down problems in MSI log files by searching for value 3. Note the comments regarding internationalization. When adding conditional features, it's more intuitive to set the default feature level to 0 (disabled) and then set the condition level to your desired value. If you set the default feature level >= 1, the condition level has to be 0 to disable it, meaning the condition logic has to be the opposite to what you'd expect, which can be confusing :) <Feature Id="NewInstallFeature" Level="0" Description="New installation feature" Absent="allow"> <Condition Level="1">NOT UPGRADEFOUND</Condition> </Feature> <Feature Id="UpgradeFeature" Level="0" Description="Upgrade feature" Absent="allow"> <Condition Level="1">UPGRADEFOUND</Condition> </Feature>
其他回答
环境变量
在将Wxs文档编译为wixobj代码时,可以使用环境变量来确定各种信息。例如,假设您想要更改项目中包含的文件。让我们假设你有一个名为RELEASE_MODE的环境变量,你在构建MSI之前设置了它(无论是用脚本还是手动设置,都没关系)在你的wix源代码中,你可以这样做:
<define FILESOURCE = c:\source\output\bin\$(env.RELEASE_MODE) >
然后在稍后的代码中,在适当的地方使用它来动态地更改WXS文档,例如:
<Icon Id="myicon.ico" SourceFile="$(var.FILESOURCE)" />
使用Heat.exe砸碎脸和造成“史诗Pwnage”痛苦的大安装
扩展Si的和 Robert-P关于热的回答。 翻译: (使用heat可以避免手动将单个文件输入到项目中,并且可以自动化构建,从而使整个过程更容易。) 详细介绍WiX 2.0热语法
For newer versions (not all that different from older versions but there are potentially annoying syntax changes....) go to the directory Heat is in from the cmd.exe and just type in heat but I have a example one right here for help with newer versions if needed. Adding the following to your Build Event in visual studio 2010. (Right Click Project->Properties ->Build Events-> Pre-Build Events) $(WIX)bin\heat.exe" dir "$(EnviromentVariable)" -cg GroupVariable -gg -scom -sreg -sfrag - srd -dr INSTALLLOCATION -var env.LogicPath -out "$(FragmentDir)\FileName.wxs -gg Generates Guids when heat is run(as in when you execute the command above) -scom Dont grab "COM files" -sreg Dont grab "Registry Files" -sfrag Dont grab "Fragments" -srd Dont grab the "root Dir" dir dir indicates you want Heat to look in a folder "$(EnviromentVariable)" The name of the variable you would add to the Preprocessor variables in the (Right click project, Go to properties) project properties->Build section where it says Define preprocessor variables (assumes visual studio 2010) Example: EnviromentVariable=C:\Project\bin\Debug;No double quotes but end with a semicolon -cg GroupVariable The ComponentGroup that will be referenced from the fragment created to the main wxs file FragmentDir The fragment directory where the output wxs fragment will be stored FileName.wxs The the name of the file Full tutorial here, So freakin helpful Part 1 Part 2
我们将产品版本显示在GUI的第一个屏幕的某个位置(很小)。因为人们每次都倾向于在选择正确版本时犯错误。(这让我们开发人员找了很长时间。) 我们已经设置了TFSBuild来生成转换(。MST文件)为我们不同的环境配置。(我们知道需要部署到的所有环境)。
由于Grant Holliday的原始博客帖子已经关闭,我复制粘贴了它的内容:
MSBuild任务从xml3月11日2008生成MSI转换文件
在我之前的文章中,我描述了如何使用MSI Transform (*.mst)文件将特定于环境的配置设置从通用MSI包中分离出来。
尽管这为您的配置提供了一定程度的灵活性,但Transform文件有两个缺点:
它们是二进制格式的 您不能“编辑”或“查看”转换文件。您必须应用它或重新创建它,以查看它包含哪些更改。
幸运的是,我们可以使用Microsoft Windows安装程序对象库(c:windowssystem32msi.dll)打开MSI“数据库”并创建转换文件。
感谢Alex Shevchuk -从MSI到WiX -第7部分-使用转换自定义安装,向我们展示如何用VbScript实现这一点。基本上,我所做的就是以Alex为例,使用Interop.WindowsInstaller.dll实现了一个MSBuild任务。 MSBuild任务
下载源代码和示例transforms.xml (~7Kb压缩VS2008解决方案)
使用InstEd代替ORCA,这是一个查看MSI表的好工具。此外,它还具有区分两个包的能力 比较…
此外,一个附加版本与额外的功能是可用的。但免费版也为逆戟鲸提供了一个很好的选择。
在退出对话框中添加一个复选框来启动应用程序或帮助文件。
...
<!-- CA to launch the exe after install -->
<CustomAction Id ="CA.StartAppOnExit"
FileKey ="YourAppExeId"
ExeCommand =""
Execute ="immediate"
Impersonate ="yes"
Return ="asyncNoWait" />
<!-- CA to launch the help file -->
<CustomAction Id ="CA.LaunchHelp"
Directory ="INSTALLDIR"
ExeCommand ='[WindowsFolder]hh.exe IirfGuide.chm'
Execute ="immediate"
Return ="asyncNoWait" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT"
Value="Launch MyApp when setup exits." />
<UI>
<Publish Dialog ="ExitDialog"
Control ="Finish"
Order ="1"
Event ="DoAction"
Value ="CA.StartAppOnExit">WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT</Publish>
</UI>
如果这样做,“标准”外观就不太正确。复选框总是灰色背景,而对话框是白色的:
可选文字 http://www.dizzymonkeydesign.com/blog/misc/adding-and-customizing-dlgs-in-wix-3/images/exit_dlg_1.gif
解决这个问题的一种方法是指定您自己的自定义ExitDialog,使用一个位置不同的复选框。这是可行的,但似乎很多工作只是改变一个控件的颜色。另一种解决相同问题的方法是对生成的MSI进行后处理,以更改控制表中特定CheckBox控件的X,Y字段。javascript代码如下所示:
var msiOpenDatabaseModeTransact = 1;
var filespec = WScript.Arguments(0);
var installer = new ActiveXObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql = "UPDATE `Control` SET `Control`.`Height` = '18', `Control`.`Width` = '170'," +
" `Control`.`Y`='243', `Control`.`X`='10' " +
"WHERE `Control`.`Dialog_`='ExitDialog' AND " +
" `Control`.`Control`='OptionalCheckBox'";
var view = database.OpenView(sql);
view.Execute();
view.Close();
database.Commit();
在MSI生成后(从light.exe)运行这段代码作为命令行脚本(使用cscript.exe)将产生一个看起来更专业的ExitDialog:
可选文字 http://www.dizzymonkeydesign.com/blog/misc/adding-and-customizing-dlgs-in-wix-3/images/exit_dlg_2.gif