Programmatically installing MSI packages

36,305

Solution 1

I find the Deployment Tools Foundation project mentioned above to be a solid way to do this from .NET. Having referenced Microsoft.Deployment.WindowsInstaller.dll, use code like this to install a package:

Installer.SetInternalUI(InstallUIOptions.Silent);
Installer.InstallProduct(msiFilename, "ACTION=INSTALL ALLUSERS=2 MSIINSTALLPERUSER=");

The documentation for the .NET wrapper is in a .chm file in the Windows Installer XML installation directory in Program Files. Some parts of that DLL loosely wrap the native Windows APIs so the documentation here can be useful as well, which is how I worked out the string in the above snippet to suit my situation.

Solution 2

There's a COM object that offers an API for the installer:

First add a reference to COM object "Microsoft Windows Installer Object Library" to your project. Then you can start with the following code:

using System;
using WindowsInstaller;

namespace TestApp
{
    public class InstallerTest
    {
        public static void Install()
        {
            Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
            Installer installer = (Installer)Activator.CreateInstance(type);
            installer.InstallProduct("YourPackage.msi");
        }
    }
}

And there's a documentation about the Installer Object.

Solution 3

The "Deployment Tools Foundation" project which is a part of the WIX3.5 install contains a .NET wrapper for most (if not all) of the Windows Installer API. Get it by downloading and installing the WiX install: http://wixtoolset.org/ (currently WiX 3.11, updated Aug.2017).

Locate the Microsoft.Deployment.WindowsInstaller.dll file in the %ProgramFiles%\Windows Installer XML v3.??\SDK\ folder. Set a reference in your C# project and try to run the different APIs and see if you get the desired functionality.

I highly recommend using Deployment Tools Foundation over any COM Interop from .NET code.

Solution 4

The basic Win32 API (that can be pinvoked if necessary) is MsiInstallProduct. This is where practically all other mentioned APIs and calls will end up.

https://msdn.microsoft.com/en-us/library/aa370315(v=vs.85).aspx

Just pass the full path to the MSI file and your command line (including quiet options etc) and check the result to see if it installed correctly.

Note that there is a simple p/invoke declaration for managed code:

[DllImport("msi.dll", CharSet = CharSet.Auto, SetLastError=true)]

static extern UInt32 MsiInstallProduct(string packagePath, string commandLine);

Solution 5

The very simplest solution is to use msiexec to invoke the installer on the .msi.

You can customise the installation using command line settings including setting .msi properties, silent installation etc.

Share:
36,305
ShdNx
Author by

ShdNx

Updated on December 29, 2020

Comments

  • ShdNx
    ShdNx over 3 years

    I would like to install a given .msi package programmatically from my C# .NET application, preferably with the installation parameters that my application specifies (like the installation path, decline crapware, etc.).

    I did some searches, but I haven't really found anything useful. The most promising hit was this topic, but I cannot find any documentation of Microsoft.Deployment.WindowsInstaller or of WindowsInstaller.Installer for that matter.

  • ShdNx
    ShdNx about 13 years
    According to the documentation, the InstallProduct will display the GUI wizard to the user. My aim would be to completely automate the installation. Do you have an idea for that?
  • Codo
    Codo about 13 years
    Have you tried "installer.UILevel = MsiUILevel.msiUILevelNone;"? I've never used it. But it's worth a try.
  • ShdNx
    ShdNx about 13 years
    Thanks, I'll give it a try, but I was hoping that there was some online documentation that could have given me some hints...
  • Stein Åsmul
    Stein Åsmul about 10 years
    Check the help file at %ProgramFiles%\Windows Installer XML v3.5\doc\DTF.chm. Also check out: wix.tramontana.co.hu/tutorial
  • cheran
    cheran almost 6 years
    How to check whether MSI installation is completed or not? Please guide me to achieve this.
  • Sнаđошƒаӽ
    Sнаđошƒаӽ about 4 years
    How can I detect completion of an msi installer? Is Process.WaitForExit sufficient?