views:

29

answers:

1

We're currently in the process of upgrading our build scripts from 3.0 to 3.5, and fixing a bunch of old ICE errors along the way. I've read through a number of articles, but I'm slightly confused as to what is usually the best approach to using companion files.

Now, assuming File A.manifest is a companion file to A.exe...

Originally: our old build breaks up the 2 files in 2 components:

<Component Guid="*" Id="A.exe" SharedDllRefCount="yes">
    <File Id="..." KeyPath="yes" Source="A.exe"/>
</Component>
<Component Guid="*" Id="A.exe.manifest" SharedDllRefCount="yes">
    <File CompanionFile="A.exe" Id="..." Source="A.exe.manifest"/>
</Component>

Which triggers ICE54: WARNING Component 'A.exe.manifest' uses file 'A.exe.manifest' as its KeyPath, but the file's version is provided by the file 'A.exe', so I guess it's obviously wrong.

1st approach: So I tried adding KeyPath=yes to the companion's directory:

<Component .../>
<Component Guid="*" Id="A.exe.manifest" SharedDllRefCount="yes" KeyPath="yes">
    <File CompanionFile="A.exe" Id="..." Source="A.exe.manifest"/>
</Component>

This suppresses the warning, but in Orca the KeyPath column of the component shows as blank, so I have doubts it's correct?

2nd approach: Next I tried combining the components:

<Component Guid="*" Id="A.exe" SharedDllRefCount="yes"> <!-- GUID is wrong! -->
    <File Id="..." KeyPath="yes" Source="A.exe"/>
    <File CompanionFile="A.exe" Id="..." Source="A.exe.manifest"/>
</Component>

But it seems that allowing WiX to automatically generate the GUIDs here wouldn't work. But if I have the GUIDs manually generated, each time we build it would break component rules when upgrading! We actually deploy a lot of companion files, so generating a hash of each component and permanently storing it might be unfeasible too. Ditto for using a dummy registry key for each companioned file.

TLDR: Which of the 2 approaches is actually the better practice in WiX?

+1  A: 

My question would be what problem are you trying to solve in doing this? In general, unless you have a really strong understanding of the component rules and the servicing implications of using/not using companion files, you should probably stick to a 1:1 component:file ratio where all files are key files. This is not an absolute rule but it's probably 95-99% optimal.

That said, take a look at the KeyPath attribute on the File element and remember that when a component doesn't have data in the KeyPath column of the MSI, that means the components directory is the key path.

Christopher Painter
Hmm, I've presumed that generally it is a Good Idea to set unversioned/unversionable files as a companion file to a DLL or EXE, so that during upgrades/uninstallation the companion files would be added or removed correctly - is that true? I also understand that Windows Installer is capable of handling unversioned files with modification time and MsiFileHash, but we've never tried it before. Is the feature reliable enough?
Jerry Chong
Yes, it's reliable. It depends what you want to happen to that file. As a companion file, when the keyfile gets updated all the files get updated. As it's own keyfile, it's modification time drives the decision. What if a user/process tweaks the file after it's been installed? Do you want those tweaks whacked during the next upgrade or do you want them left alone and the file no longer copied?
Christopher Painter
Ah, almost all of these files except a few are actually installed to Program Files and Common Files so they are never modified by the user. With this I guess it's best to just make them their own keyfile as you suggest. 2. But from the "File Versioning Rules" if an unversioned file is modified afterwards it is never overwritten, so assuming it's its own keyfile how do I force it to do so?
Jerry Chong
Do a search for "wix version lying". Basically it's a hack where you tell MSI your file has a version even though it doesn't. This changes the behavior. InstallShield calls this file level "always overwrite". This gets around the fact that REINSTALLMODE amus/omus is enforced only at the package level. The other way is to go the companion route so that when the DLL get's updated the TXT file get's updated. Unfortunatly this is just how Windows Installer is designed. It trys to protect "user data" but doesn't understand that in things like XML files.
Christopher Painter

related questions