Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

One build, multiple products?


4 replies to this topic

drl2

drl2
  • Full Members
  • 3 posts

Posted 22 March 2010 - 19:05


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 one 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 deployment project each for every possible incarnation of the product, each with its own virtual directory as the TARGETDIR. This works but is 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.


CODE

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?



Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 23 March 2010 - 13:14

You should also change the UpgradeCode, or adjust your logic for that error message (probably a custom action of type 19 with a condition base on a property that is set in the Upgrade table).

drl2

drl2
  • Full Members
  • 3 posts

Posted 23 March 2010 - 15:49

I added two more lines to my script:

cscript WiRunSQL.vbs newapp.msi "UPDATE Property SET Value='{new GUID}' WHERE Property='UpgradeCode'"

cscript WiRunSQL.vbs newapp.msi "UPDATE Upgrade SET UpgradeCode='{same GUID as above}'"

.. but the second line fails. Also tried:

cscript WiRunSQL.vbs newapp.msi "UPDATE Upgrade SET UpgradeCode='{guid}' WHERE ActionProperty='NEWERPRODUCTFOUND'"


but got the same generic 80004005 error.

With the change only successfully made in Property, I still get the Already Installed message. I could try to do this as a transform, I suppose, but that would mean generating new sets of transforms for every build (whereas with my current method I'll be able to generate GUIDs by script when new ones are required).









Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 24 March 2010 - 11:30

I'm not a SQL expert and I don't see right now why your command fails. For testing purposes you could open the msi file in Orca or InstaEd and change that UID manually to verify that this actually solves your problem. If it does (which I thinkl it does) you need to find out why your SQL command fails.

drl2

drl2
  • Full Members
  • 3 posts

Posted 24 March 2010 - 15:44

I wasn't able to alter an existing row in the Upgrade table, but can drop and re-add it with a new UpgradeCode.

I'm also experimenting with using the method here: http://msdn.microsof.....28VS.85).aspx - but I'm still getting the 'already installed' message.

Based on info from here and elsewhere I have met with some success using the platform SDK/scripting method. To quote myself from another forum:

QUOTE
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.