开发者

Programmatically installing MSI packages

开发者 https://www.devze.com 2023-02-28 01:36 出处:网络
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 installati

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.


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.


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.


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.


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);


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.


There are two approaches to solving your problem.

The first one as mentioned by @Glytzhkof is to use the Microsoft.Deployment.WindowsInstaller .NET wrapper API. This is some seriously powerful stuff but requires some time to get familiar with. You can get the latest version here (UPDATE: Stein Åsmul 28.12.2018: DTF is now part of the WiX toolkit).

The other approach is to use Transforms (.MST files). Transform files can be generated using Microsoft Orca or InstallShiled. The MSTs contains all the customizations that you need and can be applied on the MSI using this command line:

msiexec /i somemsi.msi TRANSFORMS=somemst.mst /qb

Additionally you can pass parameters directly in the command line:

msiexec /i <somemsi.msi> /qb AGREETOLICENSE=YES INSTALLDIR=C:\Temp
etc...

However, you will need to edit the MSI in an ORCA/InstallShield to determine which parameters are actually used.

The parameters used in the above example are not universal.

The actual installation can be complicated because of the presence of custom actions etc. In fact there is a whole industry that is built around msi customizations. Its called Applications Repackaging.

0

精彩评论

暂无评论...
验证码 换一张
取 消