Is there a way to recache the MSI package without reinstalling?

The reason i need to do this is that my existing live installation contains a bug in a custom action condition. A vbscript is firing in an upgrade scenario to my next version when it should only be firing in a complete uninstall scenario. The installation is massive, it's a complete data warehouse app that takes anywhere from 30 mins to 2 hours to run with some pretty complicated custom actions and SQL scripts that I would rather not reinstall just to recache the package for a custom action condition change.

Any ideas?
0 Comments   [ + ] Show Comments

Comments

Please log in to comment

Community Chosen Answer

2
I have faced a similar problem on at least a couple of occasions before. One possibility would be to use a script which can hunt out the correct cached MSI and modify the condition entry in (for example) the InstallExecute sequence.

Here's a code sample to get you started - it doesn't include any error checking, so I'd strongly advise you add some, if possible.


' This code sample will modify the condition to read REMOVE~=ALL on a ficticious custom action, DefectiveCustomAction, in the cached MSI for a given installed product.
'
' You'll need to modify the ProductCode, the custom action name and the condition itself according to your own requirements.
Const msiOpenDatabaseModeTransact = 1
' Enter Your own ProductCode in the following constant
Const ProdCodeToModify = "{00000000-0000-0000-0000-000000000000}"
Dim installer, sProductCode, sProductName, sMsiCache
Dim sQuery1, query, view, databasePath, database, openMode
Dim bProdFound

openMode = msiOpenDatabaseModeTransact

bProdFound = False
Set installer = Nothing

Set installer = CreateObject("WindowsInstaller.Installer")
For Each sProductCode In installer.Products
If sProductCode = ProdCodeToModify Then
sMsiCache = installer.productInfo(sProductCode, "LocalPackage")
bProdFound = True
End If
Next
If bProdFound Then
databasePath = sMsiCache
' Alter the folllowing query to substitute your own custom action name and the condition you wish to update.
' Please be careful to preserve all the quotes exactly as below
sQuery1 = "UPDATE `InstallExecuteSequence` SET `InstallExecuteSequence`.`Condition`='REMOVE~=ALL' WHERE" &
"`InstallExecuteSequence`.`Action`='DefectiveCustomAction'"
Set database = installer.OpenDatabase(databasePath, openMode)
Set view = database.OpenView(sQuery1)
view.Execute
database.Commit
view.Close
set database = Nothing
End If
Set installer = Nothing
wscript.quit


Regards,

Spartacus
Answered 07/06/2009 by: spartacus
Black Belt

Please log in to comment
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.

Answers

0
Thanks very much for you help. I was hoping it was easier than that and that I was being a bit dumb. I was thinking of using a similar script to yours though, but rather than hunting out the local package and modifying it at install time, i was thinking of creating a table only copy (which the cache copy is anyway) and just dropping the new file over which would be a lot easier, especially seeing as I can play with the original in Installshield or Orca. Do you see any issues in that? There isn't any kind of checksum going on with cache MSIs are there?
Answered 07/08/2009 by: cbragg
Senior Yellow Belt

Please log in to comment
0
Hello again,

In theory, what you suggest could work. Might I suggest that rather than creating a table copy, you could just modify the original base MSI to alter the condition and then perform a test installation on a clean machine.

You would then have access to a cached copy of the MSI with the necessary changes. This could then be use to overwrite the original cached copies of the MSI on the other affected machines.

If you use InstallShield to make the change, you should remember to make sure that the PackageCode is the same on the modified MSI as the original because I think InstallShield generates a new PackageCode by default.

You would still need some code to hunt out the original cached package (if it exists) because, as you are aware, the filename of the cached MSI is partially randomised and will vary from machine to machine - and you would need to know which file to overwrite :-)

Regards,

Spartacus
Answered 07/08/2009 by: spartacus
Black Belt

Please log in to comment
0
KISS; Skip the copy cached MSI idea.
Go with spartacus script instead to update the already inplace cached msi.
Answered 07/08/2009 by: AngelD
Red Belt

Please log in to comment
0
It appears that a full MSI can be used to overwrite a cached copy with binaries in it which is fine for me because the MSI is quite small but just takes time running SQL scripts rather than bulk file drops. I already had a script like the one you suggested that finds the local cache filepath for a product code so i just use that to replace the file.

Thanks for your help, much appreciated [:D]

Microsoft, just now need to make it a little easier for those that bodge their previous installers upgrade logic to be able to stream a patch in WITHOUT reinstalling for those like me that just need the MSI tables updated and not the actual installation. You'll never know until you write the next one [:o]
Answered 07/08/2009 by: cbragg
Senior Yellow Belt

Please log in to comment
Answer this question or Comment on this question for clarity