0

I'm testing the compatibility of two products (A) and (B) within a TestAutomation project. The test verifies that product (B), which is actually the product under test, can be installed eventhough (A) is already installed --> to do so, the installer of (B) looks up if the UpgradeCode of (A) is present.

NOTE: I already know the UpgradeCode of (A). What I'm trying to do is to write it into the table that will be looked-up upon installing (B), WITHOUT actually installing the MSI of (A) - this is kind of like a "mock" in integration-testing.

The test is running on a VM where (A) is not already installed by default. My goal would be to write a script which would allow me to skip the "real" installation of (A).

QUESTIONS:

  1. I'm not sure of where it looks the UpgradeCode up. It is NOT looking it up in the registries (I aready tried that hack). I have found the UpgradeCode within the Win32_Property table... is that the right place to look into?

  2. My guess is that I have to emulate the API-call, with which the original MSI from (A) sets its UpgradeCode... any idea of how that works? Possibly with a Powershell script. I have seen online people modifying the WMI properties tables can with calls to gwmi (then using put) or swmi, but all my attempts so far failed.

NOTES:

  • I do not really know my way around with the Windows Installer nor with PowerShell... this is not at all what I usually do. An answer in Layman terms would be much appreciated.
  • I know that there are other ways around this (e.g. a dedicated VM or performing a "real" installation of (A)), but I'd like to know how to achieve this programmatically.
  • Why I need to do that? It's an automated test that only concerns the installer of (B). I do not want the success of my test to be depending from (A)'s successfull download or installation.
PLB
  • 881
  • 7
  • 20
  • If you know the code is shown by a `Win32_Product` lookup, can't you simply check the return from that and skip the install step if it finds the correct one? I would avoid hacking the registry directly as this could break the installer and cause future problems. – boxdog Jun 01 '18 at 15:19
  • I'm not sure I got it but I think the answer is no, I can't: I'm not working on the installer at all. I'm just doing automated testing with the (B) installer and I'm not touching the installers themselves (A or B) The Win32_Property table does not have the entry for (A) on the VM. That's what I'm trying to hack-in. – PLB Jun 01 '18 at 16:33
  • you are not reading the comment by @boxdog correctly. It refers to the Win32_Product class not the Win32_Property table. – EBGreen Jun 01 '18 at 16:53
  • Well as I said my knowledge is limited in this specific field. I wouldn't know what the Win32_Product really refers to (I had seen that he had written it like this). But anyway my understanding of his comment is that I should ksip some step in the installer. This is not what I'm trying to do. I do not have access to any installer's code. This is black-box testing. – PLB Jun 01 '18 at 16:56
  • The comment indicates that your testing code could do a WMI query looking at the Win32_Product class to see if the software is installed already or not. – EBGreen Jun 01 '18 at 16:58
  • again, I may be confused or creating confusion, but the software is NOT installed, I already know that since I manage the VM. The whole point is that I want my VM to *think* that the software is installed. – PLB Jun 01 '18 at 17:01
  • oh and btw I'm actually not even sure that the look-up happens in the Win32_Product (or Win32_Property) tables. That's another thing I was hoping to find out here (that's question 1.) – PLB Jun 01 '18 at 17:02
  • Have you asked the makers of the MSI how they detect the other installation? It is probably done via a custom action. You can disable such a custom action by setting properties (if the setup supports it) or use a transform file to change the installer database before installing. The latter construct (transform) can also be used to change the upgrade table before installation (which is another way the setups can check for each other's existence on the target machine). – Stein Åsmul Jun 01 '18 at 17:03
  • 1
    MSIs as a general rule do not use a custom action to determine if a product is installed or not. They use the MSI API. Upgrade Code, Product Code, and Package Code all have very specific meanings and uses. Here is a good explaination: https://blogs.msdn.microsoft.com/pusu/2009/06/10/what-are-upgrade-product-and-package-codes-used-for/ – EBGreen Jun 01 '18 at 17:14
  • thanks @EBGreen I'll have a look into it – PLB Jun 01 '18 at 17:31
  • @SteinÅsmul - thanks, as well, but since I want to test the installer (B) I do not want to "tamper" it. In other words: I want to use B's installer as-it-is, and possibly I'm trying not to use A's installer – PLB Jun 01 '18 at 17:31
  • 2
    Transforms are separate files from the MSI file itself, and change the MSI in memory leaving the original file untouched. It is a little "database fragment" that gets applied to the original database. – Stein Åsmul Jun 01 '18 at 17:35
  • @SteinÅsmul cool, I'll have a look into it. Do you know any good example? Still I'm not sure that is what I want to do. In another comment you mentioned I might be able to "delete the whoel upgrade table". I just want to mock one entry in BEFORE running the MSI of B. "Changing the MSI in memory" would mean force the MSI of B to deviate from its standard behavior, if I understand that correctly. – PLB Jun 01 '18 at 17:46
  • 1
    I suppose you can [**check this answer**](https://stackoverflow.com/a/1055861/129130) for more on transforms and PUBLIC properties. Also note that to install only part of an MSI, you can go `msiexec.exe /i MySetup.msi ADDLOCAL="FeatureToInstall"`. This latter approach could mean you can get A installed in seconds rather than minutes since you only install parts of it. This can dramatically speed up the installation of large MSI packages. Note that some features can be set to be mandatory for the install. – Stein Åsmul Jun 01 '18 at 17:52
  • [**There are several free MSI tools**](https://stackoverflow.com/questions/48482545/how-can-i-compare-the-content-of-two-or-more-msi-files/48482546#48482546) you can use to generate MST files (transforms - or database fragments if you like). You apply an MST like this: `msiexec.exe /i MySetup.msi TRANSFORMS="MyTransform.mst"` etc... – Stein Åsmul Jun 01 '18 at 18:00
  • thank you again, I'll have a look into your link. Yes I'm aware of msiexec and the problem is not really the time for installing A (it's a few minutes... of course I'd like to get rid of them because we have a lot of tests that are "just a few minutes" ). I was rather hoping to get rid completely of A's installer since I do not need it. – PLB Jun 01 '18 at 18:02
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/172265/discussion-between-stein-asmul-and-plb). – Stein Åsmul Jun 01 '18 at 18:08

2 Answers2

3

The easiest way to do a test without installing the actual A would be to produce a small MSI with the same UpgradeCode and ProductCode and install it. I can't see why you want to "fake" it when you can just do the real thing.

If you want to prevent the install of B when A is already installed you could add A's UpgradeCode to B with OnlyDetect=yes, that will set a property that can be used to prevent B from being installed. It's not clear what the context is for not installing B, whether you have external launchers, a bootstrapper, or which tool is being used to generate the MSI (because some tools will give you help if you want to skip B if A is installed with their built-in detection features).

PhilDW
  • 20,260
  • 1
  • 18
  • 28
  • Alternatively he could use a transform to delete the whole Upgrade table from the installing setup to prevent detection of any pre-existing installations? Weird scenario - not sure I really understand it properly. – Stein Åsmul Jun 01 '18 at 17:27
  • thanks @PhilDW I am not an MSI developper, I am doingTEST AUTOMATION. It makes a lot of sense in this optic to keep things independent. I'm only interested in testing a reaction of B: it must tell me "hey, stop, A is already installed". I have both MSIs at hand, so no need to generate a "small MSI for A". My problem is that I don't want to be depending from A's installation. This is exactly like a mock in integration testing... – PLB Jun 01 '18 at 17:37
  • Is the real problem that A takes long to install? Does it have several features? Could you install only one feature - making the install very quick? Just trying to install your motivation and needs. I don't think you can "hotfix" the MSI database in a safe manner. – Stein Åsmul Jun 01 '18 at 17:41
1

You can get the UpgradeCode via WMI (Win32_Property WMI table) or via MSI API (Windows Installer Database - registry).

I would not hack the upgrade code in the Windows Installer Database for any reason. Why do you need to fake the UpgradeCode? Is the install of product A very large?

  1. WMI / PowerShell / VBScript:

  2. MSI API:

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • nope sorry this is not what I'm trying to do. I alfready know the upgrade code that (B) is looking for. I need to force-write it in the tables. Thanks though. – PLB Jun 01 '18 at 16:46
  • Updated the answer, why do you need this hacking? We need exact details. Plus the **real purpose**, not just how you do things now. – Stein Åsmul Jun 01 '18 at 16:47
  • thanks, just noticed it. It's for TA. I'm testing product (B) so I don't want my test to be depending from the installation of (A): if (A)'s download fails, or if its installation fails, or (...plenty of other reasons...) then my test will fail before even getting to the part where (B) is needed. I'm onlyi nterested in installing (B), so I don't want to insert "uncertainties" in my test. – PLB Jun 01 '18 at 16:52
  • So let me see if I understand the situation. Product B will not install unless Product A is already installed? So you want a way to make it look like Product A is installed whether it is or not? – EBGreen Jun 01 '18 at 17:17
  • @EBGreen: sorry I overlooked your comment. Yes, kind of (actually: product B must be installable although A is already installed. I.e. B will install if A is missing but must still install if A is present... but that's kind of the same logic). I'm trying to "mock" the installation of A, possibly through a simple script. My guess was that uf an MSI can modify the tables then PowerShell should be able to do that too, but I haven't found a way yet. – PLB Jun 04 '18 at 06:47