Is it possible to check which MSI packages depend on a specific package?

随声附和 提交于 2020-07-10 08:32:25

问题


As in title, when I have some MSI package, is it possible to see which other packages depend on it? If yes, how?

If that's not possible, is it at least possible to tell Msiexec to uninstall all depending packages as needed?


回答1:


In short: yes and no. I guess. Several MSI files can be installed in sequence without there being any reliable way to tell if they are actually related as products, but they can also be bundled together by various mechanisms so they can install as a "single unit" (suites or bootstrappers, see below), but they still might not be "tagged" as belong together after installation.


Bundling MSI Setups Together (Launchers, Bootstrappers, Suites)

Commercial tools such as Installshield have "setup suites" I think they are called. I believe they can even have a single entry in Add/Remove Programs, but that I am not sure of (we don't always have access to all the latest versions of commercial tools).

WiX - the open source framework for delivering MSI files - has a feature called Burn (and maybe even other mechanisms that I am not up to speed with). It allows you to run several MSI files in sequence with a launcher GUI.

There are also other solutions, or bootstrappers as I call them (here is one, untested by me), for installing MSI files in sequence or rather for installing prerequisite runtime components.

People can also roll their own launchers or installer GUIs that run MSI installers or other install types "under the hood" in whatever sequence desired. The installer for Visual Studio comes with such a GUI where you can select different packages to install.

The point is that by running these launchers and checking what they install you can get an idea of setups that "belong together". Check the vendor download site and see what is included in the bundle.


Related MSI Setups (Upgrade Table and Installation Location)

There are also some other clues for when MSI files relate to each other. The "Upgrade table" inside an MSI will specify related products (and hence related MSI files that were used to install them) that are to be either detected only or detected and uninstalled as part of the installation of your new MSI file. This is part of the upgrade mechanism of Windows Installer and is referred to as a major upgrade. There is a great deal of flexibility in this table, so that you can detect product and not uninstall them but continue, or you can detect products and refuse to install (for example if a higher version MSI is found installed). Note that the upgrade table generally does not detect other, related products (though it can), but rather different versions of the same product that are to be upgraded as part of the major upgrade operation. As a technical tidbit I added a section below on how to find all related product codes for a specified upgrade code.

Finally, and this is perhaps the easiest "clue" - you can check the MSI's primary installation location under the ProgramFilesFolder hierarchy. This location will normally feature a company name and a product name along these lines: ProgramFilesFolder\Company Name\Product Name - and you can add to that potentially a major version name. MSI files installing to the same Company Name folder would likely be related.

And check towards the bottom of this answer for a possible way to use the "Install Date" of MSI packages to determine what packages installed at the same time (indicating being related). Likewise the "Manufacturer / Publisher" for the MSI file can indicate "common descent". As can potentially the "Install Source" as well (the location on disk from where the install originally ran or was initiated).


I hope this answers your question. As Urman indicates, it is difficult to tell what prerequisite packages are needed for an MSI that was installed, but you can use dependency scanners to determine what runtimes the main application binaries have to get a clue. It all depends on what your problem really is and what you are trying to figure out.

Merge modules, which Urman mentions, are compiled into each MSI - a form of static linking I suppose - and you can hence see that this prerequisite is needed for the MSI that has it embedded.


Technical Tidbit: Finding Related Product Codes

You can find all installed MSI files that share the same upgrade code by running the following VBScript. You must input a valid upgrade code (found in the property table of the MSI you want to find related products for).

The actual MSI API call is Set upgrades = installer.RelatedProducts(upgradecode) - the rest of the code is supporting structure. A sample upgrade code you can try might be {AA783A14-A7A3-3D33-95F0-9A351D530011} - Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148 (if you have it installed). It is one of 3 related MSI packages, so you get 3 product codes back - provided the package is installed in the first place:

Dim relatedproductcodes, upgradecode : relatedproductcodes = "No related product codes found"
Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
upgradecode = InputBox("Please paste or type in the upgrade code you want to find all related product codes for." + _
              vbNewLine + vbNewLine + "Upgrade codes are found in an MSI's Property table, if it has been defined.", + _ 
              "Find Related Product Codes:")
If upgradecode = vbCancel Or Trim(upgradecode) = "" Then
   WScript.Quit(0)
End If

On Error Resume Next
Set upgrades = installer.RelatedProducts(upgradecode)
If (Err.number <> 0) Then
   MsgBox "Invalid upgrade code - aborting.", vbCritical, "Fatal error."
   WScript.Quit(2) ' Following exit code "standard" from MSI SDK automation samples
End If

If upgrades.Count > 0 Then relatedproductcodes = ""

For Each u In upgrades
    relatedproductcodes = relatedproductcodes & u & vbNewLine
Next

MsgBox "The related product codes for the specified Upgrade Code: " + vbNewLine + vbNewLine + relatedproductcodes

I doubt this will do much for you, I just figured I'd show you how in case it is useful. If it is, then I have a more comprehensive script for my own use which will generate a whole list of MSI pertinent information as a html export - including related product codes.

UPGRADE: In fact, looking at such an html export I can see the "Install Date" list showing pretty much the installation order for every MSI package on the box - which is another indication of packages that installed together and hence can be related. It should be noted that this date is not necessarily the original date for the install, but its latest "modify operation". So it can't be relied upon.

Sample output:




回答2:


No to both. Windows Installer tracks dependencies on packages to components, but nothing between packages. In some cases you may be able to infer package-level dependencies, for instance by reading system searches, but there's nothing native to Windows Installer here.

This is part of the reason you see some tension between people who recommend installing the Visual C++ run times as a separate .msi (or .exe) and those who recommend installing it by incorporating its merge module. The former is much easier to reason about, but only the latter will do proper reference counting of packages that depend on it.



来源:https://stackoverflow.com/questions/47854660/is-it-possible-to-check-which-msi-packages-depend-on-a-specific-package

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!