(Long) Shortcuts
Shortcuts are a basic concept in installers... and doing them with WiX is easy...
once you know how... I just spent the last 10 minutes trying to get an Icon assigned to an advertised shortcut, here's how you do it...
<Component Id="StandAloneApplication" Guid="C8D5DB05-2D68-40e8-88D1-EF5BEA18DBE1">
<File Id="SomeCompanySomeProductHostApp"
Name="SomeCompany.SomeProduct.HostApp.exe"
DiskId="1"
Source="..\..\build\SomeCompany.SomeProduct.HostApp.exe"
Vital="yes">
<Shortcut Advertise="yes"
Id="SomeCompanySomeProductHostAppShortcut"
Directory="ProgramMenuDir"
Name="My Product"
WorkingDirectory="INSTALLDIR"
Description="SomeProduct Application"
Icon="HostAppShortcutIcon.exe">
<Icon Id="HostAppShortcutIcon.exe"
SourceFile="..\..\build\SomeCompany.SomeProduct.HostApp.exe" />
</Shortcut>
</File>
</Component>
The oddity is the way the Icon must be named with an ".exe" extension for it to work.... For non-advertised shortcuts you can get away with just leaving the icon out altogether.
Now something else my client wanted that I had to wrestle with a bit... how to create an uninstall shortcut for your product in the program menu's directory... here's how I achieved it, by creating a shortcut to msiexec.exe - I'm damn sure there must be easier way though, this is very clunky, but at least it works for now - if anyone knows an easier way then drop me a comment...
Personally I think uninstall links in the program menu are a waste of time... but in this case I wasn't the target audience I guess :P
Note: The "$(var.PRODUCTGUID)" refers to a constant being passed to WiX from my continuous integration build (I have a custom msbuild task for generating a single unique productId guid per revision in SVN)...
First off I define a couple of custom actions...
<CustomAction Id="SetUninstallArgs" Property="UNINSTALLARGS" Value="/x $(var.PRODUCTGUID)" />
<CustomAction Id="SetUninstallCmd" Property="UNINSTALLCMD" Value="MSIEXEC.EXE" />
I then evaluate them as part of the "InstallExecuteSequence" ... this doesn't actually have to be run before "FindRelatedProducts"... you can evaluate them quite late in the installation process.
<InstallExecuteSequence>
<Custom Action="SetUninstallArgs" Before="FindRelatedProducts" />
<Custom Action="SetUninstallCmd" Before="FindRelatedProducts" />
And then we can create our shortcut...
<Component Id="Uninstaller" Guid="0454D0FC-190C-42c9-9506-DBA17DECBCB2">
<RegistryKey Action="createAndRemoveOnUninstall" Root="HKCU" Key="Software\MyProduct\Uninstaller">
<RegistryValue Value="" Type="string" KeyPath="yes" />
</RegistryKey>
<Shortcut Id="InvokeRemove" Name="Uninstall" Target="[UNINSTALLCMD]" Arguments="[UNINSTALLARGS]" WorkingDirectory="SystemDir" Directory="ProgramMenuDir" Description="Uninstall" />
</Component>
You might be wondering why I place a dummy registry entry in there... well it's because otherwise you end up with an
ICE 38 error - which seems daft to me, but then I don't really know enough about the windows installer architecture to dispute ICE's errors ;o) (ICE stands for Internal Consistency Evaluator(s) - which is used to validate the installer produced by WiX - have a
look here for more info).
At any rate... I like the way WiX works... I would never go back to a gui-based setup project tool again, they might be fine for small projects, but once your project grows it just starts to suck hard... why? well... 4 reasons off the top of my head:
- You can't diff between versions easily... just what did you coworker change in the setup last checkin?
- Lack of global search and replace...
- Generally a little more difficult to fit into CI builds.
- Some of the products require you to use regasm or CLR code to register assemblies for com interop.
I just wish there was a decent cookbook... WiX has been going for over 2 years now, and It still seems a little hard to find decent information, I mostly rely on the official stuff... and of course examining how some open source projects have build their installers.
I might post a little bit on upgrades next time, that's the other task that took me a little time to get sorted, might proove useful to someone starting out with WiX... who could say.
BTW - I haven't forgotten about my LINQ series... It's just on the back burner at the moment.