/build/static/layout/Breadcrumb_cap_w.png

Single MSI --> Multiple products

I've been asked to take a look at cleaning up our build and deployment process for a couple of .NET web apps. We need to be able to install multiple copies of the exact same code, each as a distinct product. So on one server we might have something like this:

Test Version for Customer A
QA Version for Customer A
Test Version for Customer B
QA Version for Customer B
... etc.

Currently this is done by maintaining one Visual Studio deployment project each for every possible incarnation of the product, each with its own virtual directory as the TARGETDIR. This works but is a maintenance mess; multiple deployment projects have to be updated if a change is made, and this scheme lends itself to creating inconsistent version numbers across deployment packages.

Ideally the goal is to build a single base MSI from a single deployment project, then use scripts to make as many copies of that as necessary and customize each one. I'm trying to do this using the VBS scripts that come with MS platform SDK. So for example I'll generate "original.msi", make a copy to "newapp.msi", and try the following to change the ProductCode, ProductName, PackageCode, and target virtual dir.


cscript WiRunSQL.vbs newapp.msi "UPDATE Property SET Value='{replacement GUID here}' WHERE Property='ProductCode'"

cscript WiRunSQL.vbs newapp.msi "UPDATE Property SET Value='Not the same product' WHERE Property='ProductName'"

cscript WiSumInf.vbs newapp.msi 9={another replacement GUID}

cscript WiRunSQL.vbs newapp.msi "UPDATE CustomAction SET Target='New Virtual Dir' WHERE Source='TARGETVDIR'"



This method successfully makes the above changes, and based on my (admittedly rather limited) knowledge of MSIs, I believe that the distinct ProductCode and PackageCode should be enough that Windows will recognize the applications installed by original.msi and newapp.msi as distinct... but it doesn't work.

If newapp.msi is run after original.msi (or vice-versa), I get "Unable to install because a newer version of this product is already installed" as if the PackageCode hadn't been changed. Is there something I'm missing here?

0 Comments   [ + ] Show comments

Answers (7)

Posted by: drl2 14 years ago
Senior Yellow Belt
1
ORIGINAL: pjgeutjens

basically what this check does is make sure that you don't install say, version 4.0.0 of your application over version 5.0.0. There are a number of actions you can take here, ranging from reasonably elegant to rather crude...


I'm still not sure why UpgradeCode issues would cause the Already Installed issue when ProductCode and PackageCode are different between the different MSIs. When I copy an MSI and try to turn it into a different product, do I also need to specify a new UpgradeCode (common, I'm assuming, to all non-major releases of the "new" product) and plug that code into the Upgrade table? I want the actual version number to be consistent across all products for a given build of the base code.

(Also, I seem to be unable to update the Upgrade table with WiRunSQL.vbs. I just get an 80004005 error.)
Posted by: pjgeutjens 14 years ago
Red Belt
0
Unable to install because a newer version of this product is already installed

This to me looks like the work of the Downgrade Prevention checks that often get built into msi's.
Have a look at your MSI's Upgrade table, make sure there's no check being done on an (I assume still identical) UpgradeCode for your packages.

PJ
Posted by: drl2 14 years ago
Senior Yellow Belt
0
There's a NEWERPRODUCTFOUND line in Upgrade - should I just delete it? What are the repercussions of this?
Posted by: pjgeutjens 14 years ago
Red Belt
0
There's a NEWERPRODUCTFOUND line in Upgrade - should I just delete it? What are the repercussions of this?

basically what this check does is make sure that you don't install say, version 4.0.0 of your application over version 5.0.0. There are a number of actions you can take here, ranging from reasonably elegant to rather crude...

1) you can modify the version range that the installer checks for in this check. Rather than explain this in detail I'm going to refer you to the Windows Installer Help files (or basically "Upgrade Table" when searched in Google). Have a look at the attributes column, VersionMinInclusive etc...

2) Change the upgrade code for your packages too, this will however "sever" the last link they had identifying your packages as being related

3) If you must, delete the entry in the Upgrade table, but remember there's a reason for 1) and 2) [;)]

Hope this helps

PJ
Posted by: jmcfadyen 14 years ago
5th Degree Black Belt
0
this is probably a more appropriate method to handle this

http://msdn.microsoft.com/en-us/library/aa369528(VS.85).aspx
Posted by: pjgeutjens 14 years ago
Red Belt
0

http://msdn.microsoft.com/en-us/library/aa369528(VS.85).aspx


there ya go, I learn something new every day.

after 6 years + of packaging this is the first time I've run into this newinstance thing. Probably says more about me... but hey [:D]

Awesome

PJ
Posted by: drl2 14 years ago
Senior Yellow Belt
0
I created a transform with a different product name, product code, and target directory, used MSIexec to apply it as specified on the MSDN page referenced above... and got the same 'Already installed' error. I'm using insted to build the transform, and it doesn't let me edit the summary info in a transform for some reason. Do I need to provide new package & upgrade codes as well? Assuming I can get this method working, would a transform created for one build of a product work against future builds or is it tied to a specific base MSI file (i.e. would I need to build new transforms on a regular basis)?

I was able to modify an MSI for a second instance via the platform SDK using the following method, given a set of GUIDs that are assigned specifically to the "new product" for its lifetime (with the possible exception of PackageCode changes for major version releases):

- Copy base MSI to newapp.msi
- Change the product code, product name, target virtual directory, upgrade code
- Retrieve the current row from the Upgrade table where ActionProperty = NEWERPRODUCTFOUND
- Drop the row from Upgrade
- Insert a new NEWERPRODUCTFOUND row into Upgrade using the values retrieved from the old, substituting the new UpgradeCode from above
- Change the package code

If my massive day and a half of MSI experience isn't leading me astray, this scheme should work to create however many instances I need of a single installer, built from a single VS deployment project in any version of Visual Studio (we have some 2003 code to maintain), while maintaining consistent version numbers across products. I can even set it up so the list of products & GUIDs is maintained in a single CSV or XML file and a single script will loop through that and generate all the needed installers.
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.
 
This website uses cookies. By continuing to use this site and/or clicking the "Accept" button you are providing consent Quest Software and its affiliates do NOT sell the Personal Data you provide to us either when you register on our websites or when you do business with us. For more information about our Privacy Policy and our data protection efforts, please visit GDPR-HQ