使用 C# 以编程方式卸载软件
Posted
技术标签:
【中文标题】使用 C# 以编程方式卸载软件【英文标题】:Programmatically Uninstall a Software using C# 【发布时间】:2015-07-16 01:44:45 【问题描述】:我想使用我的代码卸载软件,我已经尝试了 wmic 方法来执行卸载,但它无法在系统中找到我的软件。是否可以在不使用 msi 文件或任何安装文件的情况下进行卸载。我找到了这段代码,但它不起作用---
public string GetUninstallCommandFor(string productDisplayName)
RegistryKey localMachine = Registry.LocalMachine;
string productsRoot = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products";
RegistryKey products = localMachine.OpenSubKey(productsRoot);
string[] productFolders = products.GetSubKeyNames();
foreach (string p in productFolders)
RegistryKey installProperties = products.OpenSubKey(p + @"\InstallProperties");
if (installProperties != null)
string displayName = (string)installProperties.GetValue("DisplayName");
if ((displayName != null) && (displayName.Contains(productDisplayName)))
string uninstallCommand = (string)installProperties.GetValue("UninstallString");
return uninstallCommand;
return "";
【问题讨论】:
“但它不起作用”是一个无用的问题陈述。 所以你能建议我一个方法来做到这一点...... 这看起来像是 ***.com/questions/334490/uninstall-without-msi-file 的副本。唯一可靠的方法是使用:“msiexec.exe /x your-product-code-guid” 我建议你用“它不起作用”来描述你的意思。 我使用 installshield 创建一个包并静默安装,现在我想静默卸载它,我的问题是,是否可以不使用 msi 文件或安装文件 【参考方案1】:最可靠的方法是以编程方式执行以下 shell 命令:
msiexec.exe /x PRODUCT-GUID
如果您制作了原始 MSI,您将可以访问您的 PRODUCT-GUID,这就是您所需要的。不需要实际的 MSI 文件,因为 Windows 正是为了这个目的而隐藏了这个文件的副本。
仅供参考:
Windows ® Installer. V 5.0.14393.0
msiexec /Option <Required Parameter> [Optional Parameter]
Install Options
</package | /i> <Product.msi>
Installs or configures a product
/a <Product.msi>
Administrative install - Installs a product on the network
/j<u|m> <Product.msi> [/t <Transform List>] [/g <Language ID>]
Advertises a product - m to all users, u to current user
</uninstall | /x> <Product.msi | ProductCode>
Uninstalls the product
Display Options
/quiet
Quiet mode, no user interaction
/passive
Unattended mode - progress bar only
/q[n|b|r|f]
Sets user interface level
n - No UI
b - Basic UI
r - Reduced UI
f - Full UI (default)
/help
Help information
Restart Options
/norestart
Do not restart after the installation is complete
/promptrestart
Prompts the user for restart if necessary
/forcerestart
Always restart the computer after installation
Logging Options
/l[i|w|e|a|r|u|c|m|o|p|v|x|+|!|*] <LogFile>
i - Status messages
w - Nonfatal warnings
e - All error messages
a - Start up of actions
r - Action-specific records
u - User requests
c - Initial UI parameters
m - Out-of-memory or fatal exit information
o - Out-of-disk-space messages
p - Terminal properties
v - Verbose output
x - Extra debugging information
+ - Append to existing log file
! - Flush each line to the log
* - Log all information, except for v and x options
/log <LogFile>
Equivalent of /l* <LogFile>
Update Options
/update <Update1.msp>[;Update2.msp]
Applies update(s)
/uninstall <PatchCodeGuid>[;Update2.msp] /package <Product.msi | ProductCode>
Remove update(s) for a product
Repair Options
/f[p|e|c|m|s|o|d|a|u|v] <Product.msi | ProductCode>
Repairs a product
p - only if file is missing
o - if file is missing or an older version is installed (default)
e - if file is missing or an equal or older version is installed
d - if file is missing or a different version is installed
c - if file is missing or checksum does not match the calculated value
a - forces all files to be reinstalled
u - all required user-specific registry entries (default)
m - all required computer-specific registry entries (default)
s - all existing shortcuts (default)
v - runs from source and recaches local package
Setting Public Properties
[PROPERTY=PropertyValue]
【讨论】:
当然,只需添加/quiet
。您还可以通过查看msiexec /?
的结果来探索许多其他选项。【参考方案2】:
试试这个
我们使用以下格式获得一个 ManagementObject 属性:
列出已安装应用程序的完整代码块:
using System.Management
private List<string> ListPrograms()
List<string> programs = new List<string>();
try
ManagementObjectSearcher mos =
new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach (ManagementObject mo in mos.Get())
try
//more properties:
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa394378(v=vs.85).aspx
programs.Add(mo["Name"].ToString());
catch (Exception ex)
//this program may not have a name property
return programs;
catch (Exception ex)
return programs;
现在我们有了已安装应用程序的列表,我们应该能够将 [Name] 属性传递给我们的卸载方法。
我们现在需要调用 Win32_Product 方法来“卸载”
这里是卸载应用程序的整个区块,你看后我会详细的。
private bool UninstallProgram(string ProgramName)
try
ManagementObjectSearcher mos = new ManagementObjectSearcher(
"SELECT * FROM Win32_Product WHERE Name = '" + ProgramName + "'");
foreach (ManagementObject mo in mos.Get())
try
if (mo["Name"].ToString() == ProgramName)
object hr = mo.InvokeMethod("Uninstall", null);
return (bool)hr;
catch (Exception ex)
//this program may not have a name property, so an exception will be thrown
//was not found...
return false;
catch (Exception ex)
return false;
【讨论】:
这是如何“工作”的?我让if(mo["Name"].ToString().Contains("Skype")) object hr = mo.InvokeMethod("Uninstall", null);
从我的机器上卸载 Skype,但即使在代码运行之后,Skype 仍然存在。
遇到与@Ron16 相同的问题。有没有人找到解决方案? Ron16 在哪里可以找到任何解决方案?【参考方案3】:
这是一个老问题,回答可能为时已晚,但无论如何这是我的代码
public static void UninstallApplication(string uninstallString)
if (string.IsNullOrEmpty(uninstallString))
throw new ArgumentNullException(nameof(uninstallString));
ProcessStartInfo startInfo = new ProcessStartInfo();
int indexofexe = uninstallString.IndexOf(".exe");
//Check for executable existence
if (indexofexe > 0)
uninstallString = uninstallString.Replace(@"""", string.Empty);
//Get exe path
string uninstallerPath = uninstallString.Substring(0, indexofexe + 4);
startInfo.FileName = uninstallerPath;
//Check for arguments
if (uninstallerPath.Length != uninstallString.Length)
string args = uninstallString.Substring(uninstallerPath.Length);
if (!string.IsNullOrEmpty(args))
/*If not set to false You will get InvalidOperationException :
*The Process object must have the UseShellExecute property set to false in order to use environment variables.*/
startInfo.UseShellExecute = false;
startInfo.Arguments = args;
//Not tested
else
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/c " + uninstallString;
//Start the process
Process.Start(startInfo).WaitForExit();
这适用于我的大多数应用程序
【讨论】:
以上是关于使用 C# 以编程方式卸载软件的主要内容,如果未能解决你的问题,请参考以下文章