c# Visual Studio 2015 - 如何创建卸载其他应用程序的安装程序
c# Visual Studio 2015 - how to create a Setup which uninstall other application
最初我创建了一个应用程序,我在第二个版本中完全重写了它。这是一个完全不同的 Visual studio 解决方案。
现在我希望它的安装程序卸载以前的版本,但是因为它不是使用相同的解决方案创建的,所以以前版本的自动卸载不起作用。
有什么方法可以强制安装程序根据产品名称或产品代码卸载某些应用程序吗?
我发现一个 WMIC 命令在从命令行运行
时有效
wmic product where name="XXXX" call uninstall /nointeractive
所以我创建了一个 VBS 脚本来执行包含 WMIC 代码的 bat 文件,并将它添加到安装项目中
dim shell
set shell=createobject("wscript.shell")
shell.run "uninstallAll.bat",0,true
set shell=nothing
但是当我 运行 结果 MSI 时,它会触发错误 1001,这意味着服务已经存在。 ,换句话说,卸载不起作用。
旧程序仍然存在,他们创建了一个同名服务。 :/
有什么建议吗?
有2个选项:
您可以增加 MSI 项目的版本,这样它就会被视为升级,并且在安装时不会抛出任何错误。
另一种方法是在安装程序项目中写一些如下:
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);
安装结束,但没有卸载。
有人知道如何解决这个问题吗?
最初我创建了一个应用程序,我在第二个版本中完全重写了它。这是一个完全不同的 Visual studio 解决方案。 现在我希望它的安装程序卸载以前的版本,但是因为它不是使用相同的解决方案创建的,所以以前版本的自动卸载不起作用。
有什么方法可以强制安装程序根据产品名称或产品代码卸载某些应用程序吗?
我发现一个 WMIC 命令在从命令行运行
时有效wmic product where name="XXXX" call uninstall /nointeractive
所以我创建了一个 VBS 脚本来执行包含 WMIC 代码的 bat 文件,并将它添加到安装项目中
dim shell
set shell=createobject("wscript.shell")
shell.run "uninstallAll.bat",0,true
set shell=nothing
但是当我 运行 结果 MSI 时,它会触发错误 1001,这意味着服务已经存在。 ,换句话说,卸载不起作用。 旧程序仍然存在,他们创建了一个同名服务。 :/
有什么建议吗?
有2个选项:
您可以增加 MSI 项目的版本,这样它就会被视为升级,并且在安装时不会抛出任何错误。
另一种方法是在安装程序项目中写一些如下:
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);
安装结束,但没有卸载。
有人知道如何解决这个问题吗?