Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<ol> <li><p>Keep variables in a separate <code>wxi</code> include file. Enables re-use, variables are faster to find and (if needed) allows for easier manipulation by an external tool.</p></li> <li><p>Define Platform variables for x86 and x64 builds</p> <pre><code>&lt;!-- Product name as you want it to appear in Add/Remove Programs--&gt; &lt;?if $(var.Platform) = x64 ?&gt; &lt;?define ProductName = "Product Name (64 bit)" ?&gt; &lt;?define Win64 = "yes" ?&gt; &lt;?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?&gt; &lt;?else ?&gt; &lt;?define ProductName = "Product Name" ?&gt; &lt;?define Win64 = "no" ?&gt; &lt;?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?&gt; &lt;?endif ?&gt; </code></pre></li> <li><p>Store the installation location in the registry, enabling upgrades to find the correct location. For example, if a user sets custom install directory. </p> <pre><code> &lt;Property Id="INSTALLLOCATION"&gt; &lt;RegistrySearch Id="RegistrySearch" Type="raw" Root="HKLM" Win64="$(var.Win64)" Key="Software\Company\Product" Name="InstallLocation" /&gt; &lt;/Property&gt; </code></pre> <p><strong>Note</strong>: WiX guru <a href="https://stackoverflow.com/users/23852/rob-mensching">Rob Mensching</a> has posted an <a href="http://robmensching.com/blog/posts/2010/5/2/The-WiX-toolsets-Remember-Property-pattern" rel="nofollow noreferrer">excellent blog entry</a> which goes into more detail and fixes an edge case when properties are set from the command line.</p> <p>Examples using 1. 2. and 3.</p> <pre><code>&lt;?include $(sys.CURRENTDIR)\Config.wxi?&gt; &lt;Product ... &gt; &lt;Package InstallerVersion="200" InstallPrivileges="elevated" InstallScope="perMachine" Platform="$(var.Platform)" Compressed="yes" Description="$(var.ProductName)" /&gt; </code></pre> <p>and</p> <pre><code>&lt;Directory Id="TARGETDIR" Name="SourceDir"&gt; &lt;Directory Id="$(var.PlatformProgramFilesFolder)"&gt; &lt;Directory Id="INSTALLLOCATION" Name="$(var.InstallName)"&gt; </code></pre></li> <li><p>The simplest approach is always do <a href="http://blogs.technet.com/b/alexshev/archive/2008/02/15/from-msi-to-wix-part-8-major-upgrade.aspx" rel="nofollow noreferrer">major upgrades</a>, since it allows both new installs and upgrades in the single MSI. <a href="https://stackoverflow.com/questions/114165/how-to-implement-wix-installer-upgrade/724098#724098">UpgradeCode</a> is fixed to a unique Guid and will never change, unless we don't want to upgrade existing product.</p> <p><strong>Note</strong>: In WiX 3.5 there is a new <a href="http://wix.sourceforge.net/manual-wix3/wix_xsd_majorupgrade.htm" rel="nofollow noreferrer">MajorUpgrade</a> element which makes life <a href="http://www.joyofsetup.com/2010/01/16/major-upgrades-now-easier-than-ever/" rel="nofollow noreferrer">even easier</a>!</p></li> <li><p>Creating an icon in Add/Remove Programs</p> <pre><code>&lt;Icon Id="Company.ico" SourceFile="..\Tools\Company\Images\Company.ico" /&gt; &lt;Property Id="ARPPRODUCTICON" Value="Company.ico" /&gt; &lt;Property Id="ARPHELPLINK" Value="http://www.example.com/" /&gt; </code></pre></li> <li><p>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:</p> <pre><code>&lt;Target Name="CopyToDeploy" Condition="'$(Configuration)' == 'Release'"&gt; &lt;!-- Note we append AssemblyFileVersion, changing MSI file name only works with Major Upgrades --&gt; &lt;Copy SourceFiles="$(OutputPath)$(OutputName).msi" DestinationFiles="..\Deploy\Setup\$(OutputName) $(AssemblyFileVersion)_$(Platform).msi" /&gt; &lt;/Target&gt; </code></pre></li> <li><p>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.</p> <pre><code>@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 </code></pre> <p>There's a bit going on, <code>robocopy</code> is stripping out Subversion working copy metadata before harvesting; the <code>-dr</code> root directory reference is set to our installation location rather than default TARGETDIR; <code>-var</code> is used to create a variable to specify the source directory (web deployment output).</p></li> <li><p>Easy way to include the product version in the welcome dialog title by using Strings.wxl for localization. (Credit: <a href="https://stackoverflow.com/users/592/saschabeaumont">saschabeaumont</a>. Added as this great tip is hidden in a comment)</p> <pre><code>&lt;WixLocalization Culture="en-US" xmlns="http://schemas.microsoft.com/wix/2006/localization"&gt; &lt;String Id="WelcomeDlgTitle"&gt;{\WixUI_Font_Bigger}Welcome to the [ProductName] [ProductVersion] Setup Wizard&lt;/String&gt; &lt;/WixLocalization&gt; </code></pre></li> <li><p>Save yourself some pain and follow <a href="https://stackoverflow.com/questions/1602831/wix-one-file-per-component-or-several-files-per-component/1604348#1604348">Wim Coehen's advice</a> of one component per file. This also allows you to leave out (or wild-card <code>*</code>) the <a href="http://wix.sourceforge.net/manual-wix3/wix_xsd_component.htm" rel="nofollow noreferrer">component GUID</a>.</p></li> <li><p>Rob Mensching has a <a href="http://robmensching.com/blog/posts/2010/8/2/The-first-thing-I-do-with-an-MSI-log" rel="nofollow noreferrer">neat way</a> to quickly track down problems in MSI log files by searching for <code>value 3</code>. Note the comments regarding internationalization.</p></li> <li><p>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 :)</p> <pre><code>&lt;Feature Id="NewInstallFeature" Level="0" Description="New installation feature" Absent="allow"&gt; &lt;Condition Level="1"&gt;NOT UPGRADEFOUND&lt;/Condition&gt; &lt;/Feature&gt; &lt;Feature Id="UpgradeFeature" Level="0" Description="Upgrade feature" Absent="allow"&gt; &lt;Condition Level="1"&gt;UPGRADEFOUND&lt;/Condition&gt; &lt;/Feature&gt; </code></pre></li> </ol>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload