如何在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。