Major Upgrade - .exe file not reinstalled - installation

I have a .msi file created by a program called MSICREATE and doctored using orca as follows...
InstallExecuteSequence Table
* added FindRelatedProducts with sequence 410
* added RemoveExistingProducts with sequence 1450
InstallUISequence Table
* added FindRelatedProducts with sequence 200
PropertyTable
* added RemovePreviousVersions TRUE
* added SECURECUSTOMPROPERTIES SOLARUPGRADE
* had a existing UpgradeCode with guid created by MSICREATE
* had a existing ProductVersion 12.2.12.0 created my MSICREATE
Added a Upgrade Table
* UpgradeCode same value as Upgrade in Property Table
* VersionMin null
* VersionMax 99.12.31
* Attributes 1
* ActionProperty SOLARUPGRADE (same value as SECURECUSTOMPROPERTIES in Property Table)
I also assigned a new PackageCode and a new ProductCode so the new msi had different values of PackageCode, ProductCode, and ProductVersion than the previously installed product.
When I run this msi with the product previously installed, the old product is deleted, a new program files directory created and all the files except the .exe reinstalled from the new .msi. A repair will cause the .exe to be created. If the new msi is installed AFTER removing the old product (using control panel add/remove programs), all files including the .exe are installed.
The msiexec log file is mywebspace.wisc.edu/mdorl/msilog/log3.log
The .msi is mywebspace.wisc.edu/mdorl/msilog/sbl_Major_Upgrade.msi
The only things that looks weird to me are the following lines from the log. The first, second, and fourth are files that do get installed, the third is the .exe file that does not get installed. NOTE THE NULL ACTION ON THIS ENTRY.
Action start 8:04:41: InstallValidate.
MSI (s) (18:F4) [08:04:41:671]: Feature: _MainFeature; Installed: Absent; Request: Local; Action: Local
MSI (s) (18:F4) [08:04:41:671]: Component: _24A30964F6B6462282E161248AF15827; Installed: Absent; Request: Local; Action: Local
MSI (s) (18:F4) [08:04:41:671]: Component: _7B95B32E33EB4F699B44D53CA5BC22B5; Installed: Absent; Request: Local; Action: Local
MSI (s) (18:F4) [08:04:41:671]: Component: _2FBD153583AF40C09EB9920149F7C7B7; Installed: Absent; Request: Local; Action: Null
MSI (s) (18:F4) [08:04:41:671]: Component: _38A400D7DB76479CA0EC6D643D5793CD; Installed: Absent; Request: Local; Action: Local

If you look in the log at the line 603 you will find the following:
MSI (s) (18:10) [08:04:41:827]: Disallowing uninstallation of component: {ADC6C3E9-A0CF-4AFC-9998-7B9449C8EA10} since another client exists
MSI (s) (18:10) [08:04:41:827]: Disallowing uninstallation of component: {F74907E7-607E-49D1-B613-D63A36ADB020} since another client exists
MSI (s) (18:10) [08:04:41:827]: Disallowing uninstallation of component: {B1FE4023-E176-42BC-92C3-15B8E50CFBB0} since another client exists
MSI (s) (18:10) [08:04:41:827]: Disallowing uninstallation of component: {E6F5DF5D-3460-4B44-8743-48787E68A2C1} since another client exists
This can happen if the same components are shared between multiple packages installed on the same machine. Windows Installer keeps a refcount for the components and does allow removing them until all the applications that use them are removed.
If you encounter this on your test/development machine I recommend testing on a clean VM, to ensure no other previous tests affect this one.
Also, if you know you have used the same components in packages for other applications please edit them, making sure each component has an unique GUID for each package.

A keyfile is used by Windows Installer to detect the component, along with its GUID, here are more details:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa370561(v=vs.85).aspx
As you suspected, Windows Installer is also checking the file version, which I assumed you correctly incremented in the new version. Here are the rules followed by it:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa368599(v=vs.85).aspx
You need to have the version column from the File table for the EXE set to a higher value then of the one already existent on the machine, otherwise Windows Installer will decide its better to keep the old one, because it has a higher version.

For the sake of putting some closure to this item, here's what I've discovered and what I did to fix things.
1) I'm still fuzzy on the meaning of versioned/unversioned file. I guess all .exe files ar versioned. I suppose this means that such files need corresponding versions in the File table.
2) I now understand the file table version need have no connection to the ProductVersion.
3) I have been using illegal ProductVersion Eg. 2012.02.16. I switched to using something like 12.2.16.
4) I set the .exe VS_VERSION_INFO FILEVERSION in Visual Studio and added the same value to File table Version field.
Now, all files are replaced when I do a major upgrade.

The entries in the file table ALL have no version. Why are the non .exe files treated differently and reinstalled?
I suppose the other files have their version increased. Windows Installer should apply the versioning rules on all the files from the package.
So this means it's impossible for a user to install an older version of a product using a major upgrade msi?
I don't see a solution if you want to keep the version smaller in the new package. Except of course, custom actions.
And what constitutes a legal version? In one place I see 255.255.65535 and in another I see 65535.65535.65535.65535
Both of them are correct version numbers. The latter value is usually set to a file to make sure it replaces any other existing file from the machine, i.e. its the highest version number allowed by the OS.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa368596(v=vs.85).aspx

Related

Will this work to fix missing source msi issue for repair install?

I just have faced notoriously known issue with failed repair/update install of a product when source .msi is missing.
Problem description:
Download foo.msi.
Run foo.msi.
Remove foo.msi.
run msiexec.exe /f .
Step #4 fails, however foo.msi is in local Windows Installer cache.
Details: http://www.itninja.com/question/the-msi-doesn-t-repair-when-the-install-source-is-removed-from-its-original-location-how-can-it-be-fixed
I think I have solution for this issue. It is based on altering source location list values using Windows Installer Source Location Manager API at run-time.
I'm planning to create custom action (CA) that will to the following:
Create temporary directory.
Call MsiSourceListAddSource() function passing path to just created temporary directory.
Create link to running MSI (value of DATABASE msi property) in the temporary directory. If link creation fails, just copy running MSI in the temporary directory.
Schedule this CA before ResolveSource action in InstallExecute sequence with condition this is not fresh install and not product uninstall.
That is basically it. Also I need another CA that will do clean up after CA #1.
I have working prototype already and it works nice. Questions:
Is this the wheel reinventing? Is there already some WiX extension addressing this scenario?
Are there any corner cases when MsiSourceListAddSource() doesn't work?

Visual Studio 2010 Setup Project: Overwrite a file even if it has changed?

I have a Visual Studio 2010 Setup Project and I am trying to create an Upgrade to a new version of my software.
The upgrade process is running. I properly updated the Version Number, which caused an update of the Product Code. RemovePreviousVersions is also True.
My problem is that when I upgrade my software, there is one file that may have changed on the local filesystem, in the course of running the software. I'm finding that, because the file changed, the installer refuses to overwrite it.
I want my installer to force this file to be overwritten with the new version.
Is there something I can do -- within Visual Studio, with Orca, or otherwise -- to force a file to be overwritten even if it has changed?
UPDATE: In Orca, I noticed that the "File" table includes a "FileSize" column. I believe this might be the reason the file is being ignored. If the size of the file has changed, it doesn't match. Is there any way to override this?
You can't safely change the Windows Installer replace rules, but you are getting into this situation because the upgrade mechanism first installs the upgrade on top of the older product (invoking file replacement rules) then uninstalls the old product, ref counting down and removing the product. It's the "on top" that is the issue. If you move RemoveExistingProducts in the InstallExecuteSequence from just before InstallFinalize to just after InstallInitialize you will get a complete uninstall of the older product then the install of the new upgrade. That may not work if you are expecting to keep data files around.
Otherwise you could use the RemoveFile table with Orca. You'd add an entry targeting the Component name corresponding to the file (look in the File table, and there may already be some entries in the RemoveFile table as examples). You'd set the value to be Remove on Install. The RemoveFiles action occurs before the new files are installed, so it should work.

Installsheild 2013 Upgrade not removing previous version (things to check?)

I've created a copy of InstallShield project, so all the settings should be the same. (I've done this before with success). I am using this copy to make changes to the installer project as it will be called in an automated build way. One big change I made this version of the installer project was to reference a shared network location for pre-req(s). One pre-req is another installer project that gets built before this, and pulled in the main installer.
I am testing this build locally and not through the automated build process.
I know the upgrade codes match. I have 2 upgrade codes checks for Major Updates. I also check "Any Version" setting as well.
However when I build and test out the new installer it does not remove previous entries.
I have checked here [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall] and see the app listed in there twice. I had really hoped to find the UpgradeCode in order to shed some light if that was getting messed up for some reason or another, no dice.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\installer] <- no dice
As some suggested I have browsed to the exe and tried to add the Major Upgrade item, I still get the same upgrade code.
So my questions is does anyone have anything else to check that might be holding up getting this entry out of the add-remove dialog.
Log File
MSI (c) (D0:E0) [16:26:28:649]: Doing action: FindRelatedProducts
Action 16:26:28: FindRelatedProducts. Searching for related applications
Action start 16:26:28: FindRelatedProducts.
Action ended 16:26:28: FindRelatedProducts. Return value 1.
MSI (s) (2C:68) [14:12:34:706]: Doing action: RemoveExistingProducts
Action 14:12:34: RemoveExistingProducts. Removing applications
Action start 14:12:34: RemoveExistingProducts.
Action ended 14:12:34: RemoveExistingProducts. Return value 1.
Action start 13:48:41: ISSetAllUsers.
MSI (c) (6C:9C) [13:48:41:826]: Invoking remote custom action. DLL: C:\Users\ngates\AppData\Local\Temp\MSID938.tmp, Entrypoint: SetAllUsers
InstallShield 13:48:41: Begin SetAllUsers()
InstallShield 13:48:41: Getting records from Upgrade table
InstallShield 13:48:41: UpgradeCode: {84A5CBA6-9BC8-4E99-B8AE-9327E9B78A34} MinVersion: MaxVersion: 6.38.0.448 Language: Attributes: 257
InstallShield 13:48:41: Checking related product {AD762BD7-3EA5-4DD2-8552-1474ABED7C6F}
InstallShield 13:48:41: Venus 7000 {AD762BD7-3EA5-4DD2-8552-1474ABED7C6F} 1033 6.38.0.372 ***Related***
MSI (c) (6C!E4) [13:48:41:854]: PROPERTY CHANGE: Adding IS_MAJOR_UPGRADE property. Its value is 'Yes'.
InstallShield 13:48:41: ALLUSERS of related product {AD762BD7-3EA5-4DD2-8552-1474ABED7C6F} is = 1
InstallShield 13:48:41: End SetAllUsers()
Action ended 13:48:41: ISSetAllUsers. Return value 1.
According to documentation(RemoveExistingProducts Action) it appears a return code of 1 means something got removed, so it acts like it's working...
I figured out how to do it!
On the major upgrade item, select the 2nd radio button. And set a appropriate range, for me I did 6.0.0.0 to 6.99.9.9, and that seemed to do it for me. As 7.0.0.0 will constitute a truly major release for us.

MSI package property table entries to enable update releases

I use a program called MSICREATE to generate msi packages for a piece of software. I then use orca to transform the msi package. Things work ok but users must delete the existing product before installing an update. I'd like to modify the msi package so the installer recognizes a newer or different version is being installed and removes the current version and then installs the new msi package.
What property table entries are needed?
=========
The answer given below has helped me get beyond my original problem and I thank Ciprian for his help. My major upgrade msi now deletes the existing product BUT does not completely re-install the product. My product consists of some text files, a help file, and a .exe file. The .exe file is not re-installed.
For whatever it's worth, I added answer below which summarizes what I added to my msi using orce.
I don't know how MSICREATE handles the upgrade scenario. However you could achieve this using ORCA. Here is a detailed upgrade example from MSDN.
Long story short both your packages must share the UpgradeCode. Also you must author an entry in the Upgrade table of the second package.
Here are the things I added to my msi using orca to effect a major upgrade. As I said above I still have a problem in that my .exe file is not reinstalled on a major upgrade. The .exe is added if one does a repair.
InstallExecuteSequence Table
added FindRelatedProducts with sequence 400
added RemoveExistingProducts with sequence 1450
InstallUISequence Table
added FindRelatedProducts with sequence 200
PropertyTable
added RemovePreviousVersions TRUE
added SECURECUSTOMPROPERTIES SOLARUPGRADE
had a existing UpgradeCode with guid created by MSICREATE
had a existing ProductVersion 12.2.12.0 created my MSICREATE
Added a Upgrade Table
UpgradeCode same value as Upgrade in Property Table
VersionMin null
VersionMax 99.12.31
Attributes 1
ActionProperty SOLARUPGRADE (same value as SECURECUSTOMPROPERTIES in
Property Table)
I also assigned a new PackageCode and a new ProductCode so the new msi had different values of PackageCode, ProductCode, and ProductVersion than the previously installed product.

Multiple instance MSI package fails when upgrading

This is gonna take some explaining but here it goes.
I need to author a multiple instance MSI which installs dynamic instances - i.e. instances defined when the user installs the package, not hard-coded in the MSI file. Now, I've already gone through the pains of creating a bootstrapper and using the MSI api to dynamically create a transform (MST) and apply it to the original MSI; after much tinkering, install and uninstall works fine (I'll post details as they're needed).
Basically, the MST contains transforms for ProductCode, ProductName, PackageCode (in Summary Info), changes GUIDs for all components (otherwise uninstall fails in silly ways) and the install location is protected from conflicts by the bootstrapper. Also, the bootstrapper starts the install with the command line parameter MSINEWINSTANCE=1, as detailed here.
However, I'd also like to upgrade an installed instance (via major upgrades), which is the main reason why the UpgradeCode is unique (or so I thought). However after I increment the MSI version and try to start it (again via the bootstrapper and passing in the desired instance's ProductCode via the MSIINSTANCEGUID property), it fails; the log says:
=== Verbose logging started: 12/13/2011 17:43:56 Build type: SHIP UNICODE 5.00.7601.00 Calling process: C:\Windows\SysWOW64\msiexec.exe ===
MSI (c) (5C:D0) [17:43:56:120]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg
MSI (c) (5C:D0) [17:43:56:120]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg
MSI (c) (5C:34) [17:43:56:120]: Resetting cached policy values
MSI (c) (5C:34) [17:43:56:120]: Machine policy value 'Debug' is 2
MSI (c) (5C:34) [17:43:56:120]: ******* RunEngine:
******* Product: D:\TestArea\AMLDC.msi
******* Action:
******* CommandLine: **********
MSI (c) (5C:34) [17:43:56:120]: Machine policy value 'DisableUserInstalls' is 0
MSI (c) (5C:34) [17:43:56:135]: MainEngineThread is returning 1625
=== Verbose logging stopped: 12/13/2011 17:43:56 ===
and a UI message pops up saying that 'the system administrator has set policies to prevent this installation'. Obviously that's not true (the policies would appear in the log and a rather more explicit message would be provided).
The 1625 error code seems to correspond to "ERROR_INSTALL_PACKAGE_REJECTED".
Any ideas to what I could try next? I'm thinking what the MSI engine should try to do in this case is examine the UpgradeCode, apply the original transform (which should be cached and reachable via the product code I give it via the MSIINSTANCEGUID parameter). However it's clear the engine never reaches that stage (it should be logged in the log file, right?)
Sigh, this has been much more painful than it should have been.
Edit: some time later...
Quick note on changing component GUIDs: it's only really necessary for non-file components (I have some registry entries I use to keep track of instances). If I don't change their GUID they aren't cleaned up correctly at uninstall, as detailed here. For files it works fine if the key paths are different, and I've verified that by only changing the registry component ones in my code.
So I've learned in the meantime that major upgrades probably won't work for me unless I change the UpgradeCode for each instance (because FindRelatedProducts only looks at the UpgradeCode, I think), and I tried something else before going there: minor upgrades.
Starting the installer for a new version with /fvamus together with MSIINSTANCEGUID={existing-instance-product-code} seemed to work, right up until I've tried adding a new file to the package (which I expect to happen in the future)... when of course it doesn't work (the component for the new file is not installed at reinstall, of course).
So I'll probably either have to change the UpgradeCode with the transform and see what that implies, or mess around with the output property of FindRelatedProducts through some custom actions and see if I can convince major upgrades to work that way. However the initial problem (the 1625 error) was precisely with major upgrades so not sure if I can do something about it without knowing the cause. To be entirely clear: what I pasted above is the entirety of the MSI verbose log, it doesn't seem to do anything before returning with error 1625. I also tried removing all the rows in the Upgrade table of the MSI and there was no change in behavior.
I also can't spend much more time on this silly issue so if nothing else works I'll be forced to do a silent uninstall followed by a regular install with the same settings. I cringe at the thought but if it can't be helped...
Edit: in all fairness, it probably would have gone faster if I didn't start on the MSI path altogether and coded my own installer from absolute scratch, with gzipped streams and simple xcopy. Even with a msbuild task that would have compressed the files from visual studio or something.
I just tried this
msiexec /i <package>.msi /n {<InstanceProductCode>} REINSTALL=ALL REINSTALLMODE=vomus /qb
As described here: http://msdn.microsoft.com/en-us/library/aa369528(v=vs.85).aspx
This does work for me even if i add new files to the next version of the MSI.
Couldn't you make your instances as features? Then they will be selectable during installation and upgrades works well with them. There is even special action "MigrateFeatureStates" for loading state of already installed ones.
As for components that refused to clear - probably you need to specify persistent="no" for them explicitly? Then they must be removed during uninstallation.
This has been sitting here for quite a while so I thought I'd close it. The way I went in the end was to uninstall the previous instance and do a normal install afterwards. Seems to go pretty well, all things considered; gets the job done.

Resources