Wix msi package deleting all the files during majorupgrade - wix

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.

Related

Self-deleting installer in WiX

I would like my MSI to self-delete after the installation process is complete. How can I achieve this? Anyway to do it in WIX only? Do you have to create a custom action?
For those wondering, this installer is generated on the fly and bundled to a specific configuration. After the installation is complete, the MSI file has no use anymore (the user must download a new installer with a fresh configuration to reinstall).
This isn't going to be useful, mainly because the MSI file is needed after the install is complete. Rule 31:
http://blogs.msdn.com/b/windows_installer_team/archive/2006/05/24/605835.aspx
Any kind of repair (automatic or user repair) will require the original MSI file. You're better off deleting it at uninstall time.
In general, the way I've done this type of thing is to get an executable into the user's temp location (don't install it there, copy it there with a custom action) and arrange for it to run and delete the MSI file. Just rely on eventual cleanup of the temp directory to delete the exe. However, it won't be transparent if it requires elevation to do the delete, and popups of unfamiliar programs asking for elevation may get denied.

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.

wix pass option to msi for repair

When I repair using the msi, a registry entry is properly re-created. When using the exe generated by Burn, the entry is not-recreated, unless the exe associated with the reg entry also requires compare.
I wonder if, when burn invokes msi, if it is overriding the default /fm behavior of msiexec.
That switch means "repair all required computer-specific registry entries "
Is there any way I can confirm, deny, or modify that behavior?
When planning a "Repair" operation in Burn the REINSTALLMODE is "cmuse". For a "Modify" operation the REINSTALLMODE is "cmuso". So "m" is present in both cases.
The Burn log file should say, "Planning action: Action" and that will tell you which it is doing. If you are executing a Repair operation and there is not newer version of the executable on the machine than what your MSI expects, Burn's REINSTALLMODE should work. If you are doing a "Repair", look in the generated MSI log file for the same Burn execution and see what the Component states are for the Components that are not repaired. That should help you track back to see why the Component was not fixed.
From the provided log file:
Command Line: ARPSYSTEMCOMPONENT=1 MSIFASTINSTALL=7 REINSTALLMODE=cmuse
REBOOT=ReallySuppress IGNOREDEPENDENCIES=ALL CURRENTDIRECTORY=C:\temp
CLIENTUILEVEL=3 MSICLIENTUSESEXTERNALUI=1
The lack of REINSTALL=ALL shows that EnableFeatureSelection='yes'. Either remove that attribute (or change it to the default 'no') or your BA needs to handle the OnPlanMsiFeature() callback

How can I make sure a downgraded library is installed by my MSI?

I have an MSI that setups my application. It has a single component and installs only to %PROGRAMFILES% (no shared binaries). Simplified, it looks like this
Msi file, Monday build:
Program.exe (v1.0.0)
ThirdPartyLibrary.dll (v2.0.1)
Now, if I discover a bug in the program caused by my upgrade of the ThirdPartyLibrary dll from v2.0.0 to v2.0.1, and thus revert the reference to v2.0.0, it seems my MSI doesn't automatically replace the file in the installation directory?
Msi file, Tuesday build:
Program.exe (v1.0.0)
ThirdPartyLibrary.dll (v2.0) <- downgraded
What is the best practice here to ensure that the program folder always contains exactly the binaries in my setup? Should I a) wipe everything from the setup directory before copying the new files? Is there an option (in Wix) I can use that makes the msi force an overwrite of all files regardless of version?
What if I remove a file from the setup (a file that would cause errors if present at runtime), then the only way to have a working program after the setup, would be if it deleted all files first?
You can use a msi trick. In the File table in the msi database edit the Version column and enter a higher version, 3.0 for example. This way you will take advantage of the file versioning rules.

WiX - Creating MSI and MSP for patching

I have created a configuration tool which uses WiX to create MSI and with reference to previous MSI can build MSP.
This configuration tool will be used by even customer to create their MSI and MSP.
I will deliver the installer to customer (MSI or MSP)
Here I want to make sure that when customer are using it all GUIDs ProductCode, UpgradeCode, Component ID needed to be same...
One way of maintaining is storing all GUIDs in a XML file and store it as binary in installer and when customer creating their MSI or MSP they refer to the binary file in the MSI or MSP that I have provided.
I want you see is there any other way to do that?
you need to also store .wixpdb and msi file in your archive because for MSP Wix need wixpdb for reference and creating the patch. Refering the original configuration and files only possible if you keep a copy of .wixpdb and msi.
How to create MSP is there in wix tutorial...