我可以从C ++或C#程序中提取MSI包的内容吗?

时间:2012-09-19 06:00:34

标签: c# c++ windows-installer extract

说,如果我有一个MSI安装文件,我可以从C#或C ++程序中提取其内容而不安装它吗?

2 个答案:

答案 0 :(得分:9)

通常,您可以执行Administrative installation来提取MSI的内容。

msiexec /a foo.msi TARGETDIR=C:\EXTRACTHERE /qn

如果您不想退出流程,可以通过MsiInstallProduct function直接与MSI互动。

szPackagePath [in]以null结尾的字符串,用于指定Windows Installer程序包位置的路径。字符串值可以包含URL,网络路径,文件路径(例如file://packageLocation/package.msi)或本地路径(例如D:\ packageLocation \ package.msi)。

szCommandLine [in]以空值终止的字符串,用于指定命令行属性设置。这应该是格式Property = Setting Property = Setting的列表。有关更多信息,请参阅关于属性。

要执行管理安装,请在szCommandLine中包含ACTION = ADMIN。有关更多信息,请参阅ACTION属性。

请注意,虽然您可以自己声明P / Invoke,但有一个非常好的.NET互操作库可用于Windows Instaler XML,称为部署工具基础(DTF)。 Microsoft.Deployment.WindowsInstaller命名空间有一个名为Installer的类方法,它公开一个名为InstallProduct的静态方法。这是MsiInstallProduct的直接封装。

使用DTF库可以隐藏Win32 API中的丑陋,并在需要时正确实现IDisposable,以确保在需要时释放基础非托管句柄。

此外,DTF具有带InstallPackage类的Microsoft.DeploymentWindowwsInstaller.Package命名空间。此类公开了一个名为ExtractFiles()的方法,该方法将文件提取到工作目录。代码示例如下:

using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Package;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using( var package = new InstallPackage(@"C:\test.msi", DatabaseOpenMode.ReadOnly))
            {
                package.ExtractFiles();
            }
        }
    }
}

答案 1 :(得分:4)

MSI文件是COM structured storage。它基本上是一个数据库。您可以在msdn上找到一些详细的文档:

  • Here 是数据库API
  • Here 您可以找到有关复合二进制文件格式的一些信息
  • Here 是关于Windows Installer的文档