External Handler for Msiexec Msisetexternalui

External handler for msiexec MsiSetExternalUI

I cannot see why intercepting the UI has anything to do with cache locations that you cannot alter while the install is in progress. However it's not clear exactly what usage of "cache" you are intending here. I'll assume that you are referring to the complete MSI file which may have been extracted to some location for install, or is otherwise at the location it was installed from.

Let's assume that the install has finished and you know (or can get) its ProductCode. All you need do to obtain all the official source locations is call MsiSourceListEnumSources () and that will tell you the actual locations that Windows will use to find the MSI for maintenance, upgrade, repair, etc, if and when required.

If the source MSI is at a location you do not approve of, then use MsiSourceListClearSource () to delete that entry, copy the MSI to a location of your choice, then use MsiSourceListAddSource () to add that location. There are plenty of sourcelist APIs for exactly this type of management activity, such as when products were installed from network locations that are no longer available.

I don't believe you should be moving or altering the internal cached (obfuscated name) MSI file that is typically in \windows\installer. That us sometimes referred to as the cached location, but you seem to be referring to the complete MSI used to install the product.

Installing MSI vb.net with MsiSetExternalUI

Take a look at Windows Installer XML's (Wix) Deployment Tools Framework (DTF) MSI interop library (Microsoft.Deployment.WindowsInstaller.dll ) It has all the pieces needed to invoke an installation and provide an external UI handler to receive the ProgressBar update messages that you can then route to your VB.Net UI.

See the following topic and subtopics for more information:

Monitoring an Installation Using MsiSetExternalUI

The examples are in C++ using MSI Win32 functions and the DTF interop library encapsulates all of this with classes. The DTF help file tells you which classes and methods map to which Win32 functions.

msiexec.exe -Embedding

You can find some information from
Aaron Stebner here: https://learn.microsoft.com/en-us/archive/blogs/astebner/more-info-about-how-msi-custom-actions-work-behind-the-scenes

Here is an extract:

msiexec.exe -Embedding (GUID) - this is the custom action server (indicated by the -Embedding switch)

Custom Action: A custom action is a custom piece of code that runs during installation. They can be in script or binary form - dll, exe, vbscripts, etc... Danger close. With elevated rights they can basically do "anything", but usually they are OK.

msiexec.exe: There will be numerous msiexec.exe processes during the installation of any MSI file, and some MSI files can trigger quite a few of them. This has to do with how many custom actions exist in the MSI and probably a number of other things. There will also always be a client msiexec.exe process running in user context and a server msiexec.exe process running as LocalSystem (unless the server is run silently - then there is no user part to the install). These processes run the actual installation itself.

Technical Tidbit: I believe the msiexec.exe processes remain in the process list for about 10 minutes after the install. This at least used to be normal behavior (things change). Old blog from Heath Stewart on this.

Malware: With regards to this in a malware-sense. The custom action process can certainly be infected, but most often it is not and the anti-virus software could decide to mess with it because of a false positive. System mode custom actions run elevated with temporary administrator rights and can certainly infect the computer with just about anything. Non-elevated MSI files can install trojans and other kinds of malware by launching them on startup and such things. However, elevated custom actions can install drivers and services and all kinds of madness.

Anti-Virus Blues: A common problem for MSI files is that an anti-virus could decide to quarantine an MSI in the super-hidden MSI cache folder: C:\Windows\Installer. This folder is highly protected and should not be accessed by anything, and messing around here typically causes MSI packages that can not be uninstalled (packages are cached to facilitate uninstall, modify and repair). There are some hacks and fixes for such un-uninstallable packages. Additionally, there are other reasons why the MSI source can be missing (with System Restore weirdness being one of my suspected key culprits).

Keys to the City: Having gone well beyond what you actually asked: if you are sure an MSI is infected, I would be hesitant to invoke its uninstaller... I guess that goes without saying. If it runs elevated it has "the keys to the city". Use that Microsoft FixIt tool (found in the linked answer above) or some other approach to wipe the install. Or better yet: rebuild your box I suppose - as if you are not busy enough?


Links:

  • Comprehensive list of ways to uninstall MSI packages
  • Why are there multiple msiexec.exe instances?
  • Locations where packages are cached

MsiInstallProduct() starts msiexe.exe but in 32 bit mode?

I think after two years of the code running with no issues it would be proper to conclude the workflow proposed in the Update 7 above is an answer to the question:

looks like there's some sort of internal memory management leak in the MSI API which causes the external UI handler crash in a completely random behaviour. To fix the issue, I implemented IDisposable interface and tried to use the class in a "using" block to make sure the class is completely disposed. The MsiSetExternalUI() and MsiInstallProduct() are now safely called within this block. do not forget to call the MsiSetExternalUI() to revert the UI to it's original state

Determine if MsiExec run with /passive parameter

Use UILevel property to determine at what UI level the installer runs.

Excerpt from Determining UI Level from a Custom Action:

a custom action that has a dialog box should only display the dialog when the user interface level is Full UI or Reduced UI, it should not display the dialog if the user interface level is Basic UI or None. You should use the UILevel property to determine the current user interface level.

From the description of /passive option:

The equivalent Windows Installer Command-Line Option is /qb!- with REBOOTPROMPT=S set on the command line.

It means the installer is run with Basic UI, with no modal dialogs displayed (-), with Cancel button hidden (!).

passing properties to msiexec

Yes, they get created. Once you pass a property via msiexec command line, you can address them as if you define them directly in Property table. Windows Installer gurus might point out differences (if there are), but in terms of usage I didn't notice any.

WiX Custom Action - MSI copy itself

Here's an example VB script that will find an installed product by name and copy the cached copy of the MSI. This will work on Windows 7 and later, as the full MSI is cached and any embedded cab files remain in the MSI. You just get the MSI without the payload on older systems.

Dim installer, products, product, productCode
Set installer = Wscript.CreateObject("WindowsInstaller.Installer")

For Each productCode In installer.Products
If InStr(1, LCase(installer.ProductInfo(productCode, "ProductName")), LCase("My Product Name")) Then Exit For
Next

If IsEmpty(productCode) Then Wscript.Quit 2

Set products = installer.ProductsEx(productCode, "", 7)
filesys.copyFile products(0).InstallProperty("LocalPackage"), "c:\path\to\newcopy.msi"


Related Topics



Leave a reply



Submit