说,如果我有一个MSI安装文件,我可以从C#或C ++程序中提取其内容而不安装它吗?
答案 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上找到一些详细的文档: