【问题标题】:Programmatically installing MSI packages以编程方式安装 MSI 软件包
【发布时间】:2011-08-11 12:20:35
【问题描述】:

我想通过我的 C# .NET 应用程序以编程方式安装给定的 .msi 包,最好使用我的应用程序指定的安装参数(如安装路径、拒绝垃圾软件等)。

我进行了一些搜索,但我并没有真正找到任何有用的东西。最有希望的命中是this topic,但我找不到任何关于Microsoft.Deployment.WindowsInstallerWindowsInstaller.Installer 的文档。

【问题讨论】:

  • @David Heffernan:我猜,但它会做我想做的事吗?
  • 嗯,msiexec 是调用安装程序最常用的方式
  • @David Heffernan:我查看了文档,它似乎允许非 gui 安装,但是,我看不到任何可以让我配置设置的东西(例如设置安装路径)。有什么线索吗?
  • 这一切都取决于 .msi。您需要传递特定于特定 .msi 的设置
  • @David Heffernan:我该怎么做?您能否在答案中详细说明您的想法,以便我可以接受它是否被证明是最佳解决方案?

标签: c# .net wix windows-installer dtf


【解决方案1】:

有两种方法可以解决您的问题。

@Glytzhkof 提到的第一个是使用Microsoft.Deployment.WindowsInstaller .NET wrapper API。这是一些非常强大的东西,但需要一些时间来熟悉。您可以获得最新版本 here更新Stein Åsmul 28.12.2018:DTF 现在是 WiX 工具包的一部分)。

另一种方法是使用Transforms(.MST 文件)。可以使用 Microsoft Orca 或 InstallShiled 生成转换文件。 MST 包含您需要的所有自定义,并且可以使用此命令行在 MSI 上应用:

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

另外你可以直接在命令行中传递参数:

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

但是,您需要编辑ORCA/InstallShield 中的MSI 以确定实际使用了哪些参数。

上例中使用的参数并不通用。

由于存在自定义操作等,实际安装可能会很复杂。事实上,围绕 msi 自定义构建了一个完整的行业。它叫Applications Repackaging

【讨论】:

    【解决方案2】:

    作为 WIX3.5 安装的一部分的“Deployment Tools Foundation”项目包含大多数(如果不是全部)Windows Installer API 的 .NET 包装器。通过下载并安装 WiX 安装来获取它:http://wixtoolset.org/(当前为 WiX 3.11,2017 年 8 月更新)。

    在 %ProgramFiles%\Windows Installer XML v3.??\SDK\ 文件夹中找到 Microsoft.Deployment.WindowsInstaller.dll 文件。在您的 C# 项目中设置一个引用并尝试运行不同的 API,看看您是否获得了所需的功能。

    我强烈建议在任何来自 .NET 代码的 COM 互操作上使用部署工具基础。

    【讨论】:

    • 谢谢,我会试一试,但我希望有一些在线文档可以给我一些提示......
    • 检查 %ProgramFiles%\Windows Installer XML v3.5\doc\DTF.chm 中的帮助文件。另请查看:wix.tramontana.co.hu/tutorial
    【解决方案3】:

    基本的 Win32 API(必要时可以调用)是 MsiInstallProduct。这实际上是所有其他提到的 API 和调用将结束的地方。

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

    只需将完整路径传递给 MSI 文件和您的命令行(包括静默选项等)并检查结果以查看它是否安装正确。

    请注意,托管代码有一个简单的 p/invoke 声明:

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

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

    【讨论】:

      【解决方案4】:

      我发现上面提到的 Deployment Tools Foundation 项目是从 .NET 执行此操作的可靠方法。引用 Microsoft.Deployment.WindowsInstaller.dll 后,使用如下代码安装包:

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

      .NET 包装器的文档位于 Program Files 的 Windows Installer XML 安装目录中的 .chm 文件中。该 DLL 的某些部分松散地包装了本机 Windows API,因此文档here 也很有用,这就是我如何计算出上述 sn-p 中的字符串以适应我的情况。

      【讨论】:

      • 如何查看微星安装是否完成?请指导我实现这一目标。
      【解决方案5】:

      最简单的解决方案是使用msiexec 调用.msi 上的安装程序。

      您可以使用命令行设置自定义安装,包括设置 .msi 属性、静默安装等。

      【讨论】:

      • 如何检测 msi 安装程序的完成情况? Process.WaitForExit足够了吗?
      【解决方案6】:

      有一个 COM 对象为安装程序提供 API:

      首先向您的项目添加对 COM 对象“Microsoft Windows Installer 对象库”的引用。然后你可以从下面的代码开始:

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

      还有一个关于Installer Object的文档。

      【讨论】:

      • 根据文档,InstallProduct 将向用户显示 GUI 向导。我的目标是完全自动化安装。你对此有什么想法吗?
      • 你试过“installer.UILevel = MsiUILevel.msiUILevelNone;”吗?我从来没有使用过它。但值得一试。
      猜你喜欢
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      相关资源
      最近更新 更多