我知道我们可以使用MSI通过传递命令参数来卸载Windows应用程序,如下所示,
Process p = new Process();
p.StartInfo.FileName = "msiexec.exe";
p.StartInfo.Arguments = "/x \"C:\\MyApplication.msi\"/qn";
p.Start();
但我想知道的是如何在不使用MSI的情况下卸载应用程序?在上面的场景中,我应该在特定位置安装MSI来卸载这个应用程序,如果我可以使用产品代码解压缩,那么我就不需要在目标机器上安装MSI。
答案 0 :(得分:6)
根据MSDN,您可以使用产品代码将其卸载:
msiexec.exe /x {your-product-code-guid}
使用产品代码时,它使用C:\WINDOWS\Installer
中的缓存MSI。
答案 1 :(得分:5)
根据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");
}
答案 2 :(得分:3)
可能对于您的情况,知道“/ 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
您必须使用互操作才能在C#中使用它。
或b) 使用Windows Installer对象。 例如,这个相关案例已在stackoverflow中得到解答: Programmatically installing MSI packages 但是使用此函数需要物理包,也需要卸载。 稍微间接,这是更好的卸载代码:
首先,将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而不是“安装程序对象”:-) 但是对于小的目的来说就足够了。而且更容易。
答案 3 :(得分:2)
此命令适用于命令行:
msiexec /x {3A40307D-6DF2-4412-842F-B1D848043367} /quiet
我没有在C#中尝试过,但用上面显示的键替换你的参数应该有效。您可以在要尝试卸载的应用程序的注册表项中找到GUID。