我们已经使用WiX有一段时间了,尽管人们对它的易用性有一些抱怨,但它运行得相当不错。我想要的是有用的建议:
设置WiX项目(布局、引用、文件模式) 将WiX集成到解决方案中,并构建/发布流程 为新的安装和升级配置安装程序 任何你想分享的好的WiX技巧
我们已经使用WiX有一段时间了,尽管人们对它的易用性有一些抱怨,但它运行得相当不错。我想要的是有用的建议:
设置WiX项目(布局、引用、文件模式) 将WiX集成到解决方案中,并构建/发布流程 为新的安装和升级配置安装程序 任何你想分享的好的WiX技巧
当前回答
使用RobM特殊的“记住属性”模式
http://robmensching.com/blog/posts/2010/5/2/The-WiX-toolsets-Remember-Property-pattern
其他回答
Peter Tate已经展示了如何在单独的wix片段中定义可重用的ComponentGroup定义。一些与此相关的额外技巧:
目录别名
组件组片段不需要知道主产品wxs定义的目录。在你的组件组片段中,你可以这样描述一个文件夹:
<DirectoryRef Id="component1InstallFolder">
...
</DirectoryRef>
然后主产品可以别名它的一个目录(例如。"productInstallFolder")像这样:
<Directory Id="productInstallFolder" Name="ProductName">
<!-- not subfolders (because no Name attribute) but aliases for parent! -->
<Directory Id="component1InstallFolder"/>
<Directory Id="component2InstallFolder"/>
</Directory>
依赖关系图
ComponentGroup元素可以包含ComponentGroupRef子元素。如果您有大量可重用组件,并且它们之间有复杂的依赖关系图,那么这是非常棒的。你只需要为每个组件在自己的片段中建立一个ComponentGroup,并像这样声明依赖项:
<ComponentGroup Id="B">
<ComponentRef Id="_B" />
<ComponentGroupRef Id="A">
</ComponentGroup>
如果您现在在设置中引用组件组“B”,因为它是应用程序的直接依赖项,那么它将自动拉入组件组“a”,即使应用程序作者从未意识到它是“B”的依赖项。只要你没有任何循环依赖,它就“可以工作”。
Reusable wixlib
如果您使用lit.exe将大池-o-可重用组件编译为可重用的wixlib,则上述依赖关系图的想法效果最好。在创建应用程序设置时,可以像引用wixobj文件一样引用这个wixlib。exe链接器将自动消除没有被主产品wxs文件“拉入”的任何片段。
使用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
使用InstEd代替ORCA,这是一个查看MSI表的好工具。此外,它还具有区分两个包的能力 比较…
此外,一个附加版本与额外的功能是可用的。但免费版也为逆戟鲸提供了一个很好的选择。
设置IIS enable32BitAppOnWin64标志http://trycatchfail.com/blog/post/WiX-Snippet-change-enable32BitAppOnWin64.aspx
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize" />
<Custom Action="ConfigureAppPool" After="InstallFinalize" >
<![CDATA[NOT Installed AND VersionNT64 >= 600]]>
</Custom>
</InstallExecuteSequence>
<CustomAction Id="ConfigureAppPool" Return="check" Directory="TARGETDIR" ExeCommand="[SystemFolder]inetsrv\appcmd set apppool /apppool.name:[APPPOOLNAME] /enable32BitAppOnWin64:false" />
正在安装到C:\ProductName
一些应用程序需要安装到C:\ProductName或类似的地方,但99.9%(如果不是100%)的示例安装到C:\Program Files\ CompanyName\ProductName。
下面的代码可以用来将TARGETDIR属性设置为C:驱动器的根目录(取自WiX-users列表):
<CustomAction Id="AssignTargetDir" Property="TARGETDIR" Value="C:\" Execute="firstSequence" />
<InstallUISequence>
<Custom Action="AssignTargetDir" Before="CostInitialize">TARGETDIR=""</Custom>
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action="AssignTargetDir" Before="CostInitialize">TARGETDIR=""</Custom>
</InstallExecuteSequence>
注意:默认情况下,TARGETDIR不指向C:\!相反,它指向ROOTDRIVE,而ROOTDRIVE又指向拥有最大空闲空间的驱动器的根(见这里)——这并不一定是C:驱动器。可能有另一个硬盘驱动器,分区,或USB驱动器!
然后,在<Product…>标签,您需要以下目录标签像往常一样:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="APPLICATIONFOLDER" Name="$(var.ProductName)">
<!-- your content goes here... -->
</Directory>
</Directory>