Question

Can someone please explain the odd MSI behavior in the following scenario:

I have multiple Wix projects which all share the same feature containing a single component:

<Feature Id="VTWSK" Level="1" Directory="MyCommonFolder">
  <Component Id="vtwsk" Guid="{47EC2941-738D-4486-9D86-A443A40C5F94}" Directory="TempDriversFolder">
    <File Id="vtwsk.key" Source="..." KeyPath="yes"/>
    ...
  </Component>
</Feature>

I make sure that all products resolve MyCommonFolder to the same target directory so that component key path is indeed the same. I also have a custom action which should be executed if and only if the component is installed for the first time on the target machine, so I use a following condition:

<InstallExecuteSequence>
  <Custom Action="InstallVTWSK" After="InstallFiles">$vtwsk=3</Custom>
</InstallExecuteSequence>

It works fine when the first product is installed on target machine, however, the second product fails to detect that vtwsk component is already installed. Logs from the second product installation:

MSI (s) (B0:AC) [13:18:22:202]: Feature: VTWSK; Installed: Absent;   Request: Local;   Action: Local
...
MSI (s) (B0:AC) [13:18:22:202]: Component: vtwsk; Installed: Absent;   Request: Local;   Action: Local;   Client State: Unknown

Thus, the component state is still 3, and corresponding custom action is executed for the second time (and fails, due it's nature which I can't easily control). I would rather expected "Installed: Local; Request: Local; Action: Null".

Is it even possible to run a custom action conditionally only when the component (or feature) is installed on the target machine for a first time?

Was it helpful?

Solution

All other things being correct, what's happening is that the component is installed every time so that condition is true. There are still two or three products that install that component and the reference count in that location gets incremented, and the fact that there is one file is not relevant. The component is still being installed by each product. You really want to run that CA the first time the file is installed. I'd look at having that CA create a registry item that says the file is initialized, and use it to see if it needs initializing. Or otherwise make the CA smart enough to see that the initialization has been done so you just call it every time. Or if the fact that the file is there is sufficient then you can do a search for the file's component ID and if it's there then maybe assume it's been initialized by a previous install.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top