如何在c#中使用其产品代码卸载MSI

我知道我们可以通过传递命令参数来使用其MSI卸载Windows应用程序,如下所示,

Process p = new Process(); p.StartInfo.FileName = "msiexec.exe"; p.StartInfo.Arguments = "/x \"C:\\MyApplication.msi\"/qn"; p.Start(); 

但我想知道的是如何在不使用MSI的情况下卸载应用程序? 在上面的场景中,我应该在特定的位置安装MSI来卸载这个应用程序,如果我可以使用产品代码解压缩,那么我就不需要在目标机器上安装MSI。

根据MSDN ,您可以使用产品代码卸载它:

 msiexec.exe /x {your-product-code-guid} 

使用产品代码时,它使用C:\WINDOWS\Installer的缓存MSI。

根据PhilmE的回答,Windows Installer XML(WiX)将Microsoft.Deployment.WindowsInstaller互操作库作为Deployment Tools Foundation(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"); } 

可能对于你的情况,知道“/ x”参数就足够了。 两条评论:更安全的是在命令行中添加“REBOOT = R”部分。 您可以添加日志文件路径:

 msiexec /x "..." /qn REBOOT=R /L*v "c:\mylogdir\mymsi.log" 

其次,不要试图改变任何“缓存”。 你甚至不需要理解它。 如果缓存的包将被破坏,则不再可能进行常规卸载,这可能使计算机处于“需要支持”状态。

因为你的问题最初是在谈论C#..你不必使用msiexec:

a)将原始C / C ++ API与函数MsiInstallProduct()或MsiConfigureProduct()一起使用。 MSDN参考: http : //msdn.microsoft.com/en-us/library/windows/desktop/aa370315( v = vs.85) .aspx

你必须使用interop在C#中使用它。

或b)使用Windows Installer对象。 例如,这个相关案例已在stackoverflow中得到解答:以编程方式安装MSI包但是使用此函数需要物理包,也需要卸载。 稍微间接,这是更好的卸载代码:

首先,将COM对象“Microsoft Windows Installer对象库”的引用添加到项目中。

 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而不是“安装程序对象”:-)但是对于小的目的来说就足够了。 而且更容易。

此命令适用于命令行:

 msiexec /x {3A40307D-6DF2-4412-842F-B1D848043367} /quiet 

我没有在C#中尝试过,但用上面显示的键替换你的参数应该可行。 您可以在要卸载的应用程序的注册表项中找到GUID。