More info about how MSI custom actions work behind the scenes


I received a couple of interesting questions about custom actions in response to one of my previous blog entries.  So I wanted to explain a little bit more about what is going on behind the scenes.  I’m sure many of you have noticed that when a setup is in progress, there are multiple msiexec processes running on your system.  You can use a process viewer such as tlist.exe or tasklist.exe to list the msiexec processes that are running on the system along with their command line parameters.  Here are the various types of msiexec processes along with example command lines to help you distinguish between them:

  • msiexec /i <product>.msi /l*v install.log – this is the main MSI client process for an installation when it is in progress
  • msiexec.exe /V – this is the Windows Installer service process; the service name is msiserver; in general, the msiserver service will start when an installation begins, and the service will stay running for 10 minutes after the installation completes as an optimization so that the overhead of unloading and reloading the service data does not happen if setups are run one after another
  • msiexec.exe -Embedding <GUID> – this is the custom action server (indicated by the -Embedding switch)

It can be useful to know which msiexec process is which in case you have a custom action that is not working correctly and you want to kill the custom action process but not the overall setup process.

In addition, here are some documents that have been published on MSDN about writing, securing and debugging custom actions that may be useful:

I hope that this info is useful to those of you interesting in writing and debugging setup packages.  Please let me know if you have additional questions about how Windows Installer works behind the scenes and I will try to answer them in future blog posts.

 

Comments (13)

  1. G. Man says:

    When debugging custom actions, I just attach to the only msiexec that is running managed code, which will be my custom action.

    However, I have to put a message box as the first line of code in the custom action so that the execution will stop while I attach to the process. Is there a better way to do this?

  2. Steven Bone says:

    Hey G.Man – I can’t think of a better way for either managed or unmanaged CA’s.

    For unmanaged C++, I usually pop the message box and attach to the msiexec process that owns the message box. In the CA code, after MessageBox() a DebugBreak() is placed called. When the hard break is hit, the debugger will let you step through the CA code.

    I’ve never used managed CA’s before – but I like your trick of fining the only msiexec running managed code.

  3. e says:

    Clarification request – Will MsiBreak not work for managed code? Why?

  4. I agree, the simplest way to debug a custom action is to have it pop up a message box at the beginning and then attach a debugger while the message box is on-screen. As far as I know, MsiBreak will work for managed code (as long as the managed code custom action is implemented as a DLL – MsiBreak will only work for DLL custom actions and not EXEs or scripts).

    One of the developers on my former team wrote a really nice custom action wrapper that makes it really easy to debug. I’m going to talk to him about the possibility of making this available outside of Microsoft to make things easier in the future.

    The question about mananged code brings to mind another of my pet peeves – using managed code as part of setup custom actions. I am going to write a separate blog item when I get my thoughts more organized on this topic….

  5. jan@cirpka.nl says:

    Trying to figure out how to support silent installs with custom actions that normally would pop-up a dialog this article was of great help. What I ended up doing is to specify in the dotNet setup project /uilevel=[UILevel] as customdataaction retrieving this in my custom installer class. Inspecting the other items of the context I wonder though under which conditions the logfile property is set. In my scenarios it is always empty, even if I explicitly specify a file using msiexec’s /L argument. Any ideas?

  6. Hi Cirpka – I don’t know of a way to check the logging level from within a custom action.  What scenario are you thinking of where you want to check that property?  There is some helpful information about sending messages to Windows Installer at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/sending_messages_to_windows_installer_using_msiprocessmessage.asp.  The info in that MSDN article is applicable to custom action logging in addition to other scenarios, so hopefully it will help for the scenario you are thinking of.

  7. John says:

    Try System.Diagnostics.Debugger.Break() where you want your customer action breaks. That should get you automatically attached to the installer process.

  8. Hi John – This API will work if your custom action is written in managed code, but you won't be able to do that for a native code custom action.  There is some information about another option for debugging custom actions in the blog post at blogs.msdn.com/…/388739.aspx as well.

  9. Teresa says:

    Was is a MSI is it used to write a custom made software program?

  10. Hi Teresa – You can see more information about Windows Installer and .msi files at msdn.microsoft.com/…/cc185688(v=vs.85).aspx.

Skip to main content