Installer calling Custom action even though it was removed - wix

I ran installer which contains custom action:
<Custom Action="renameIndex" Before="InstallFinalize"></Custom>
this just run one bat file which was previously installed on drive.
In never version of this installer both that custom action and bat file were removed from installer.
In the installation logs i can see that bat file is removed:
MSI (s) (A8:5C) [13:08:27:790]: Component: indexSCO.bat; Installed: Local; Request: Absent; Action: Absent
MSI (s) (A8:5C) [13:08:28:062]: Executing op: FileRemove(,FileName=indexSCO.bat,,ComponentId={EC857BEC-50CA-4DE7-B80B-D1DF4AC37CF5})
but the Custom action is still being called even though it was removed from InstallExecuteSequence
Is there any link that causes that custom action to be called because if existed in previous version of installer or I should search for mistakes in installer file?

While upgrading to newer version from previous one, by default uninstallation of previous version is invoked first. This will be launched from installer cache(C:\Windows\Installer). As the above custom action had no condition in previous version, it was triggered during uninstallation.
Once the uninstallation is completed by RemoveExistingProducts action, newer version msi InstallExecute sequence will be triggered and the new changes(removed custom action) will come into play.

Related

Can we apply transform(.mst) while uninstallation?

We found some uninstallation issue on already released msi which is creating issue during upgrade of higher version.I need to modify few custom action conditions so that it doesn't run while msi uninstallation. In order to this, transform file is generated with updated condition. However, I am not sure how to pass this during uninstallation? user can trigger uninstall from Add or Remove Programs.
Minor upgrades are not option for us as it requires release of new msi.
The locally cached MSI within the Windows folder is a transformed version of your original MSI database, if you installed it together with the MST.
Your custom actions added by MST, if they have no condition set, are always run (on install, repair and removal).
If you want to run your action only on uninstallation, set this as the condition: REMOVE="ALL" or inverted NOT REMOVE="ALL" if it should NOT run on uninstallation.
Try to place your custom action in the Table InstallExecuteSequence between InstllValidate and InstallInitialize or after InstallFinalize
You don't need the MST during uninstallation.

Change upgrade location with silent installation of WiX Installer

I have built an installer using WiX which lets the user upgrade a current installation to the next version and change the location of the install folder. This works when using the .msi file, but when running this silently using msiexec, my setting of the INSTALLDIR is overwritten later on in the installation process.
I have had a look at the logs and it is being written over with the current install directory. I have a property which searches the registry for the current install location and sets the INSTALLDIR to that value.
I guess in the .msi UI value, things are running in the right order, but with the silent install, they're not.
MSI (s) (A0:90) [09:47:34:315]: PROPERTY CHANGE: Modifying INSTALLDIR property. Its current value is 'C:\SpecifiedInSilentInstall'. Its new value: 'C:\CurrentInstallDirectoryFromRegistry\'.
Is there a way of specifying the order in a CustomAction or something?
If you are using a custom action like this
<CustomAction Id="SetInstallDir" Property="INSTALLDIR" Value="[YourInstallDir]" />
you can time it in your <InstallExecuteSequence> section like this
<Custom Action="SetInstallDir" Before="CostFinalize" />
Here you can time your events with Before and After. These events follow a specific order (taken from FIREGIANT)
AppSearch
LaunchConditions
ValidateProductID
CostInitialize
FileCost
CostFinalize
InstallValidate
InstallInitialize
ProcessComponents
UnpublishFeatures
RemoveShortcuts
RemoveFiles
InstallFiles
CreateShortcuts
RegisterUser
RegisterProduct
PublishFeatures
PublishProduct
InstallFinalize
RemoveExistingProducts
For the property INSTALLDIR it is important to set it at the right event to take effect (whatever your needs are). For me Before=CostFinalize changes the path to the one I want.

Why is my installer searching for another, non-existent MSI?

My installer has recently started crashing during an upgrade. Just after laying down files, it displays a box saying:
A network error occurred while attempting to read from the file:
C:\Users\user\AppData\Local\Temp\2\MyInstaller.msi
I am sure this error is correct because we have never shipped an file MyInstaller.msi. I ship Package.msi, bootstrap it with a custom bootstrapper as MyInstaller.exe and then, using MyInstaller.exe call msiexec /i Package.msi.
This has been working perfectly until very recently when Package.msi started failing while apparently trying to look for MyInstaller.msi. Why would it do that? Wilogutl.exe only says "A standard or custom action appears to have failed." which isn't very helpful.
I'm still not sure why this is happening but I found a possibly-relevant log section:
MSI (c) (D0:54) [09:03:23:868]: Entering CMsiConfigurationManager::SetLastUsedSource.
MSI (c) (D0:54) [09:03:23:869]: Specifed source is already in a list.
MSI (c) (D0:54) [09:03:23:869]: User policy value 'SearchOrder' is 'nmu'
MSI (c) (D0:54) [09:03:23:869]: Machine policy value 'DisableBrowse' is 0
MSI (c) (D0:54) [09:03:23:869]: Machine policy value 'AllowLockdownBrowse' is 0
MSI (c) (D0:54) [09:03:23:869]: Adding new sources is allowed.
MSI (c) (D0:54) [09:03:23:869]: PROPERTY CHANGE: Adding PackagecodeChanging property. Its value is '1'.
MSI (c) (D0:54) [09:03:23:869]: Package name retrieved from configuration data: 'MyInstaller.msi'
MSI (c) (D0:54) [09:03:23:869]: Note: 1: 2205 2: 3: Error
MSI (c) (D0:54) [09:03:23:871]: Note: 1: 2262 2: AdminProperties 3: -2147287038
MSI (c) (D0:54) [09:03:23:871]: Machine policy value 'DisableMsi' is 1
MSI (c) (D0:54) [09:03:23:871]: Machine policy value 'AlwaysInstallElevated' is 0
Another oddity: Add/Remove Programs shows that the older version is installed and my binaries confirm that. However, if I try to run the MSI for the new version directly, I receive the error message:
Another version of this product is already installed. Installation of
this version cannot continue...
I often get this error message when, during my development process, I try to install an MSI with the same version but different package codes. However, Orca says the new MSI is definitely a higher version.
Regarding your last comment about same version but different package code, the version may be somewhat irrelevant. ProductCode is what defines that a product is already installed, so attempting to install something else with the same ProductCode (but a different version) will result in that message. PackageCode matters, but most tools simply generate a new one at every build so it's not usually an issue. So if you are really doing an upgrade you should have a WiX major upgrade element and a new ProductCode AND ProductVersion increment somewhere in the first three fields.
If this is on a client system, could they have installed that other product? Do you install any fairly common items (maybe from merge modules) that may be shared with other products? For example, if you were to install a commonly shared file (Crystal Reports, C++ Dlls etc) with a Component ID that breaks sharing then you might trigger Windows to try to resolve the sharing version issue by going to another MSI file. Incidentally, this can be a common problem when MSI installs use "version lying" when the file actually being installed has a version that is not the same as the one in the File Table of the MSI file. Also, look at the Windows Event Log, Application, MsiInstaller entries because there is probably an entry with a Component ID listed as the trigger for a repair and getting a file from its containing product MSI file.
Just to make things even more confusing, a DisableMSI policy of 1 blocks some installs (see the docs).
Under circumstances unknown to myself, windows caches the file name of the MSI used to install the product initially. So when I run an older version, my bootstrapper unloads the MSI as MyInstaller.msi, and installs my product.
I recently changed the bootstrapper to unload it as Package.msi. Now, under these mysterious conditions, windows caches the file name as MyInstaller.msi and, in the middle of running Package.msi attempts to refer back to MyInstaller.msi which no longer exists.
I don't know why it's doing this or how to make it stop but I've reverted my change and am again unloading my MSI from the bootstrapper as MyInstaller.msi.

Dll is not getting uninstalled from GAC during uninstall only

I am copying a dll to GAC by specifying it in a component of one feature.
I have installed my package by selecting that feature. The dll was copied to GAC. But when perform uninstall, that dll is still left over in GAC.
During modify, I found one strange thing. After installaing my package by selecting that feature, I clicked on modify, unchecked that feature and proceeded the installation.
At that time, the dll was uninstalled from GAC.
In both cases, the feature state is showing as 2.
I found below information in log file during uninstallation.
MSI (s) (18:DC) [09:59:16:619]: Doing action: InstallValidate
MSI (s) (18:DC) [09:59:16:620]: Feature: MyFeature; Installed: Absent; Request: Null; Action: Null
And during modify
MSI (s) (18:DC) [09:59:16:619]: Doing action: InstallValidate
MSI (s) (A8:9C) [09:32:42:720]: Feature: MyFeature; Installed: Local; Request: Absent; Action: Absent

How to execute Custom Action before RemoveExistingProducts with After="InstallValidate" in WiX

I have something like this:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
Since one of the uninstallation fails i need to execute a Custom Action to solve the problem BEFORE RemoveExistingProducts. Something in the lines of:
<CustomAction Id="FixStuff" .. />
<InstallExecuteSequence>
<Custom Action="FixStuff" Before="RemoveExistingProducts" />
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
This of course doesn't work since Custom Action cannot be before InstallInitialize. I'd really like to remove existing products between InstallValidate and InstallInitialize, but i'd like to execute FixStuff before removing existing products.
Is it even possible to do that?
Unfortunately you cannot run an elevated custom action before RemoveExistingProducts with your current configuration.
Some possible approaches would be:
Move RemoveExistingProducts right before InstallFinalize. This solves the custom action problem, but other problems may occur since this approach has many restrictions (the components need to maintain their names and GUIDs between versions, your custom actions should be aware that the upgrade is performed at installation end etc.).
Create an EXE bootstrapper which fixes the old installer before launching the new MSI. This bootrapper can require Administrator privileges through a manifest:
http://msdn.microsoft.com/en-us/library/bb756929.aspx
Repair the broken MSI by using this method:
fix the problem in the old MSI
create a BAT or EXE bootstrapper which recaches it through this command:
msiexec /fv <path_to_msi>
distribute this MSI as an update before your new package
When your new package runs RemoveExistingProducts, the old cached MSI should be fixed and it should uninstall correctly.