最初我创建了一个我在第二个版本中完全重写的应用程序。它是一个完全不同的Visual Studio解决方案。现在我希望它的安装程序安装程序卸载以前的版本,但由于它不是使用相同的解决方案创建的,因此以前版本的自动卸载不起作用。
有没有办法强制安装程序根据产品名称或产品代码卸载某些应用程序?
我发现WMIC命令在从命令行运行时有效
wmic product where name="XXXX" call uninstall /nointeractive
所以我创建了一个VBS脚本,它执行包含WMIC代码的bat文件,然后将其添加到Setup项目中
dim shell
set shell=createobject("wscript.shell")
shell.run "uninstallAll.bat",0,true
set shell=nothing
但是当我运行结果MSI时,它会触发错误1001,这意味着服务已经存在。换句话说,卸载不起作用。旧程序仍然存在,并且它们创建具有相同名称的服务。 :/
有什么建议吗?
有两种选择:
protected override void OnBeforeInstall(IDictionary savedState)
{
//Write uninstall powershell script
//installutil /u <yourproject>.exe
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript("");
PowerShellInstance.AddParameter("");
}
PowerShellInstance.Invoke();
}
注意:此InstallUtil随.NET Framework一起提供,其路径为%WINDIR%\Microsoft.NET\Framework[64]\<framework_version>
。
例如,对于32位版本的.NET Framework 4或4.5。*,如果您的Windows安装目录是C:\Windows
,则路径为C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe
。
对于64位版本的.NET Framework 4或4.5。*,默认路径为C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe
我决定选择在项目安装程序中引入c#代码。首先,我通过nuget添加了System.Management.Automation的参考
https://www.nuget.org/packages/System.Management.Automation
在此之后,我刚刚创建了一个包含PS代码的字符串变量,我需要卸载几个名称相似的程序。
string unInstallKiosk = @"$app = get-WMIObject win32_Product -Filter ""name like 'KIOSK'""
foreach ($program in $app){
$app2 = Get-WmiObject -Class Win32_Product | Where -Object { $_.IdentifyingNumber -match ""$($program.identifyingNumber)""
}
$app2.Uninstall()}";
并将此变量传递给方法PowerShellInstance.AddScript()
PowerShellInstance.AddScript(unInstallKiosk);
安装结束,但卸载根本不会发生。
谁有想法如何解决这个问题?