2

I'm updating an installer written with InstallShield to perform a major upgrade of an application and have InstallScript functions invoked by custom actions to back up and restore some files from the application's directory. I have the script working with previous installation directory hardcoded but need to find the actual location that the application was installed.

I can get the location of current install using:

MsiGetProductInfo(PRODUCT_GUID, INSTALLPROPERTY_INSTALLLOCATION, savedInstallDir, bufferSize);

but if I change PRODUCT_GUID to the hardcoded value of the product code of the previous installation then I get an empty string in savedInstallDir:

MsiGetProductInfo("{my-previous-product-code}", INSTALLPROPERTY_INSTALLLOCATION, savedInstallDir, bufferSize);
t c
  • 23
  • 5

1 Answers1

2

Are you sure the installation location has been persisted for the older version that is installed? Do you get anything when you try from VBScript (update with your own product GUID of course):

Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
MsgBox installer.ProductInfo("{9B061D60-4E2C-4987-BFFD-423E3D477660}","InstallLocation")

I checked all my installed packages and only about a dozen or so (out of a few hundred packages) had this path persisted. Script to check all installed packages.


In the registry: look for the value "InstallLocation" under location:

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\PACKEDGUIDHERE\InstallProperties

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{REGULARGUIDHERE}

GUIDS:

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • That worked - thank you! I did it in InstallScript as follows: `set installer = CreateObject("WindowsInstaller.Installer"); SprintfMsiLog("BackupUserData: previous install dir %s", installer.ProductInfo("{my-previous-product-code}","InstallLocation"));` This throws an exception if the product wasn't installed but that should be easy to work around. Thanks for your help! – t c Mar 08 '21 at 10:22
  • 1
    Did you try the [MsiGetProductInfo](https://learn.microsoft.com/nb-no/windows/win32/api/msi/nf-msi-msigetproductinfoa) MSI API function via a C++ custom action? That would probably be the better option. Beware of per-user installations and such things - that can be an issue (not installed per machine). – Stein Åsmul Mar 08 '21 at 12:58
  • I'm using InstallScript for the custom action - I don't really want to get involved in introducing C++ at this point. The method in my previous comment works with a try/catch to handle the exception so I'm happy with that. – t c Mar 08 '21 at 16:05
  • 1
    OK, I have [this answer on C++ custom actions](https://stackoverflow.com/questions/54925087/interrupt-installation-when-custom-action-returns-error/54929785#54929785). It has further links to related topics. A little more complexity when you call MsiGetProductInfo from C++ - [quick example](https://github.com/tixsys/esteid/blob/a0be3c31a0390f68f042127f0498e0900d0304a5/id-updater/tags/initial_import/InstallChecker.cpp#L33). – Stein Åsmul Mar 08 '21 at 23:47