Dll is not getting uninstalled from GAC during uninstall only - dll

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

Related

Installer calling Custom action even though it was removed

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.

Wix msi package deleting all the files during majorupgrade

I am new to wix, previously, I was trying to solve the problem that major upgrade updated all the config files. I manage to fix it by schdule the RemoveExistingProduct after the installExecute. However, it brings me a new problem, major upgrade between the package I generated using current project is fine, but there is a old msi package (have same upgrade code), when I major upgrade with that old package installed, it delete everything, files can only reappear after I repair.
In the log it has
1: msvcp140_2.dll 2: 3: 4: 5: 6: 7: 8: 9: C:\Folders\
MSI (s) (5C:04) [18:29:11:453]: Verifying accessibility of file: msvcp140_2.dll
MSI (s) (5C:04) [18:29:11:453]: Note: 1: 2318 2:
MSI (s) (5C:04) [18:29:11:453]: Note: 1: 2318 2:
MSI (s) (5C:04) [18:29:11:454]: Executing op: FileRemove(,FileName=msvcp140_codecvt_ids.dll,,)
Any help would be appreciated!
The best advice I can give you is MSI wants to own the files it installs and ignores the files it doesn't.
So if MSI installs a file v1 and a user modifies it, then when a later MSI installs the file v2 it's going to be wrong if it overwrites it or doesn't overwrite it.
You can write custom actions to harvest user data from the file and reapply them after MSI overwrites the file but this gets tedious.
My general reccomendation is to design the app to have two config files.
app.config ( installed by MSI and user does not modify )
app-override.config ( not installed by MSI and user data is stored here )
The application then reads and merges the two files in memory. In this way MSI can safely always overwrite the file without any harm and the user data isn't lost and the new data from v2 isn't lost.
In this way it's all really simple and easy and you can set your RemoveExistingProducts scheduling back to where it was in the first place.
If this was a .NET app, .NET ConfigurationManager classes already support this pattern out of the box. The AppSettings element has a File attribute that can point to a second file to merge in.

WIX bootstrapper fails on MSI package with 'optional' CAB files

Using WIX 3.10:
I authored a MSI package using a few external CAB files.
Sometimes we deploy over network and we omit one or more CAB files (which contain files not needed for program execution). On installation we deselect corresponding features. There is no problem with missing CABs in that case.
Now I authored a bootstrapper with managed BA.
In chain of packages I set 'Cache=no':
<MsiPackage Id="MyInstaller"
Compressed="no" Visible="no" ForcePerMachine="yes"
EnableFeatureSelection="yes"
Cache="no"
SourceFile="$(var.MyPackageFileName)">
The problem is: on runtime the bootstrapper verifies presence of all packages and theirs CAB files (if any). It does so before the execution of all packages in the chain.
From log (shortened):
Acquiring package: MyInstaller, payload: MyInstaller, copy from: D:\X\MX-8-2-0-77-x86-Release.msi
Setting string variable 'WixBundleLastUsedSource' to value 'D:\X\'
Verified acquired payload: MyInstaller at path: C:\ProgramData\Package Cache\.unverified\MyInstaller, moving to: C:\ProgramData\Package Cache\{970B002C-448C-46E8-856C-5F9C5B234AB4}v8.2.0.77\MX-8-2-0-77-x86-Release.msi.
Acquiring package: MyInstaller, payload: cab502ABC9C22436673DD367A3B0E989121, copy from: D:\X\MX-8-2-0-77-x86-Release-Data.CAB
Verified acquired payload: cab502ABC9C22436673DD367A3B0E989121 at path: C:\ProgramData\Package Cache\.unverified\cab502ABC9C22436673DD367A3B0E989121, moving to: C:\ProgramData\Package Cache\{970B002C-448C-46E8-856C-5F9C5B234AB4}v8.2.0.77\MX-8-2-0-77-x86-Release-Data.CAB.
Prompt for source of package: MyInstaller, payload: cabBC894B366CE86BC776B6C0F16A45AEC9, path: D:\X\MX-8-2-0-77-x86-Release-HelpAndDoc.CAB
Failed to resolve source for file: D:\X\MX-8-2-0-77-x86-Release-HelpAndDoc.CAB, error: 0x80070002.
Error 0x80070002: Failed while prompting for source (original path 'D:\X\MX-8-2-0-77-x86-Release-HelpAndDoc.CAB').
Failed to acquire payload: cabBC894B366CE86BC776B6C0F16A45AEC9 to working path: C:\Users\CHRIST~1.THI\AppData\Local\Temp\{3CF902F0-06EB-46E8-BECF-900FA010D2EC}\cabBC894B366CE86BC776B6C0F16A45AEC9, error: 0x80070002.
Error 0x80070002: Failed while caching, aborting execution.
I don't want a prompt for missing files. I don't want to download missing files. And I don't want verification of CABs. Hence I disabled package caching. But WIX boostrapper host seems to ignore that.
All CAB files are also present in 'BootstrapperApplicationData.xml' which is created at compile time. But I did not mention them in bootstrapper sources. WIX burn obviously analyzes the packages.
How to make the bootstrapper host ignore missing CAB files for one MSI package?
Burn doesn't support that scenario. It assumes the .cabs in your package are needed and always verifies all packages and payloads.

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.