【问题标题】:Can I extract contents of MSI package from within C++ or C# program?我可以从 C++ 或 C# 程序中提取 MSI 包的内容吗?
【发布时间】:2012-09-11 10:38:45
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

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

    如果您不想退出进程,可以通过MsiInstallProduct function 直接与 MSI 进行互操作。

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

    szCommandLine [in] 一个以 null 结尾的字符串,用于指定命令行属性设置。这应该是 Property=Setting Property=Setting 格式的列表。有关详细信息,请参阅关于属性。

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

    请注意,虽然您可以自己声明 P/Invoke,但 Windows Instaler XML 提供了一个非常好的 .NET 互操作库,称为部署工具基础 (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();
                }
            }
        }
    }
    

    【讨论】:

    • 感谢和抱歉这次延误。只是好奇这是否可以从 ASP.NET Web 应用程序中获得?
    • 对不起,如果我问的问题很简单。当我包含您的两个“使用”行时,我得到以下信息:“错误 CS0234:名称空间“Microsoft”中不存在类型或名称空间名称“部署”(您是否缺少程序集引用?)”
    • 您必须安装 WiX 并在 WiX SDK 目录中添加对该库的引用。
    • 哦。我无法在服务器端安装任何东西。它必须是股票 IIS 库。
    • 您需要 Microsoft.Deployment.WindowsInstaller.dll 和 Microsoft.Deployment.WindowsInstaller.Package.dll 才能使代码正常工作。 (蜡的一部分)。我认为您不必安装这些。从 WIX 中获取它们并将它们包含在您的项目中。您甚至可以使用 AppDomain.CurrentDomain.AssemblyResolve 将它们嵌入并提供给您的应用程序。
    【解决方案2】:

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

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

    【讨论】:

    • 谢谢。尽管此时对我来说这一切都非常令人不知所措...任何指向可以进行提取的 C# 代码的链接?
    • 他只是想知道如何提取内容。有用于此的 API。他不需要了解二进制级别的数据库结构。
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 2018-03-26
    • 1970-01-01
    相关资源
    最近更新 更多