如何在 c# 中使用其产品代码卸载 MSI
Posted
技术标签:
【中文标题】如何在 c# 中使用其产品代码卸载 MSI【英文标题】:How to uninstall MSI using its Product Code in c# 【发布时间】:2013-07-05 15:04:35 【问题描述】:我知道我们可以使用它的 MSI 卸载 Windows 应用程序,方法是传递如下命令参数,
Process p = new Process();
p.StartInfo.FileName = "msiexec.exe";
p.StartInfo.Arguments = "/x \"C:\\MyApplication.msi\"/qn";
p.Start();
但我想知道的是如何在不使用 MSI 的情况下卸载应用程序?在上述情况下,我应该在特定位置有 MSI 来卸载此应用程序,如果我可以使用产品代码卸载,那么我不需要在目标机器中拥有 MSI。
【问题讨论】:
【参考方案1】:根据MSDN,您可以使用产品代码卸载它:
msiexec.exe /x your-product-code-guid
当您使用产品代码时,它使用来自C:\WINDOWS\Installer
的缓存 MSI。
【讨论】:
谢谢,我想知道在没有主 MSI 的情况下如何进行卸载。现在只有我知道缓存部分:)【参考方案2】:按照 PhilmE 的回答,Windows Installer XML (WiX) 将 Microsoft.Deployment.WindowsInstaller 互操作库作为部署工具基础 (DTF) 的一部分提供。这会跳过 COM 互操作并封装 Win32 API。
using Microsoft.Deployment.WindowsInstaller;
public static void Uninstall( string productCode)
Installer.ConfigureProduct(productCode, 0, InstallState.Absent, @"REBOOT=""R"" /l*v uninstall.log");
【讨论】:
【参考方案3】:可能对于您的情况,知道“/x”参数就足够了。对此有两点评论: 更安全的是在命令行中添加“REBOOT=R”部分。你可以添加一个日志文件路径:
msiexec /x "..." /qn REBOOT=R /L*v "c:\mylogdir\mymsi.log"
其次,不要尝试将任何内容更改为“缓存”。你甚至不需要理解它。如果缓存的包被破坏,则无法再进行常规卸载,这可能会使计算机处于“需要支持”状态。
因为您的问题最初是在谈论 C# .. 您不必为此使用 msiexec:
a) 使用带有函数 MsiInstallProduct() 或 MsiConfigureProduct() 的原始 C/C++ API。 MSDN 参考: http://msdn.microsoft.com/en-us/library/windows/desktop/aa370315(v=vs.85).aspx
您必须使用互操作才能在 C# 中使用它。
或 b) 使用 Windows 安装程序对象。 例如,这个相关案例已经在 *** 中得到解答: Programmatically installing MSI packages 但是使用这个功能需要物理包,也需要卸载。 稍微间接一点,这里是更好的卸载代码:
首先,在您的项目中添加对 COM 对象“Microsoft Windows Installer Object Library”的引用。
using WindowsInstaller;
public static class MyMsiLib
public static void Uninstall(string productCode)
Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer installer = (Installer)Activator.CreateInstance(type);
installer.UILevel=msiUILevelNone;
installer.ConfigureProduct(productCode, 0, msiInstallStateAbsent);
之前的 UILevel 属性在此处设置为硬编码,以确定您似乎想要的静默 UI 级别。其他属性也一样。请参阅 MSDN 文档,例如在上面的链接中提到。
当然,“真正的程序员”使用原始 API 而不是“安装程序对象”:-) 但对于小目的来说就足够了。而且更容易。
【讨论】:
仅供参考 Windows Installer XML (WiX) 将 Microsoft.Deployment.WindowsInstaller 互操作库作为部署工具基础 (DTF) 的一部分提供。这会跳过 COM 互操作并封装 Win32 API。 是的,使用上述库是第三种可能性。这是品味和使用的问题。如果您使用 MSI 做很多事情,那么这个库当然值得一试。我不太清楚。如果您将该库用于类似的开源,您可能必须满足交付软件的特殊许可要求。在生成互操作程序集后,在我看来使用本机 MSI API 并没有那么困难。但很高兴让所有感兴趣的人知道,您可以在多种可能性之间进行选择。 从技术上讲,WindowsInstaller.Installer 是 MSI.dll 公开的两个“真实”API 之一。但是,我发现 P/Invoking MSI 的问题比 COM 互操作要小得多。 DTF 库做得非常好,应该在 BCL 中提供。也就是说,如果您只需要 1 或 2 个 API 的 google“MSIInterop.cs”并将其减少到您的需要。 FOSS 参数是 FUD。 实际上 WindowsInstaller.Installer 是“基础”API 的 COM 包装器,因此它调用另一个。我同意它不像 P/Invoking MSI API 那样稳定和防弹,有几个原因。最初,它是为编写脚本任务而制作的。【参考方案4】:此命令在命令行上运行:
msiexec /x 3A40307D-6DF2-4412-842F-B1D848043367 /quiet
我没有在 C# 中尝试过,但是用上面显示的键替换你的参数应该可以。您可以在您尝试卸载的应用的注册表项中找到 GUID。
【讨论】:
以上是关于如何在 c# 中使用其产品代码卸载 MSI的主要内容,如果未能解决你的问题,请参考以下文章