VB.NET通过注册表卸载字符串无法卸载M365的问题求助
卸载Microsoft 365后仍显示在已安装应用列表的问题
我正在使用基于.NET Framework 9.0的VB.NET程序卸载Microsoft 365产品,程序提示卸载完成,但Windows已安装应用列表中仍能看到M365产品。以下是我的实现代码:
目标卸载产品列表
Dim officeProductIds As String() = { "O365ProPlusEEANoTeamsRetail", "O365ProPlusRetail", "O365BusinessEEANoTeamsRetail", "O365BusinessRetail" }
注册表卸载路径
Dim uninstallPaths As String() = { "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" }
核心卸载逻辑代码
Try Dim baseKey As RegistryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) For Each regPath In uninstallPaths Using uninstallKey As RegistryKey = baseKey.OpenSubKey(regPath) If uninstallKey Is Nothing Then Continue For For Each subKeyName As String In uninstallKey.GetSubKeyNames() If officeProductIds.Any(Function(id) subKeyName.Contains(id)) Then Dim uninstallString As String = ReadRegistry.GetOfficeUninstallString(subKeyName) If Not String.IsNullOrEmpty(uninstallString) Then Console.WriteLine($"[FOUND] Uninstall string for {subKeyName}: {uninstallString}") Dim installerPath As String = "" Dim arguments As String = "" If uninstallString.StartsWith(ChrW(34)) Then Dim endQuoteIndex As Integer = uninstallString.IndexOf(ChrW(34), 1) installerPath = uninstallString.Substring(1, endQuoteIndex - 1) arguments = uninstallString.Substring(endQuoteIndex + 1).Trim() Else Dim firstSpace = uninstallString.IndexOf(" "c) If firstSpace > 0 Then installerPath = uninstallString.Substring(0, firstSpace) arguments = uninstallString.Substring(firstSpace + 1).Trim() Else installerPath = uninstallString End If End If Dim installerFolder As String = IO.Path.GetDirectoryName(installerPath) Console.WriteLine() Console.WriteLine($"Installer: {IO.Path.GetFileName(installerPath)}") Console.WriteLine($"Install Folder: {installerFolder}") Console.WriteLine($"Arguments: {arguments}") Console.WriteLine() ApplicationInstallerHelper.UninstallApplication(IO.Path.GetFileName(installerPath), installerFolder, True, arguments) Else Console.WriteLine($"[WARNING] No UninstallString for {subKeyName}") End If End If Next End Using Next Catch ex As Exception Console.WriteLine("[EXCEPTION] " & ex.Message) End Try
卸载执行方法
Public Sub UninstallApplication(installerFileName As String, installerFolderPath As String, Optional silent As Boolean = False, Optional installerArguments As String = "") Dim fullPath As String = IO.Path.Combine(installerFolderPath, installerFileName) If Not IO.File.Exists(fullPath) Then StrBuilder.WrapMessage($"Installer not found at: {fullPath}", "ERR") Return End If If silent AndAlso Not installerArguments.Contains("/quiet") Then installerArguments &= " /quiet" End If If silent AndAlso Not installerArguments.Contains("/norestart") Then installerArguments &= " /norestart" End If Dim psCommand As String = $"Start-Process -FilePath '{fullPath}' -ArgumentList '{installerArguments}' -Wait -NoNewWindow; exit $LASTEXITCODE" Dim psi As New ProcessStartInfo("powershell.exe", $"-NoProfile -ExecutionPolicy Bypass -Command ""{psCommand}""") psi.UseShellExecute = False psi.RedirectStandardOutput = True psi.RedirectStandardError = True psi.CreateNoWindow = True Dim proc As Process = Process.Start(psi) proc.WaitForExit() Dim output As String = proc.StandardOutput.ReadToEnd() Dim errors As String = proc.StandardError.ReadToEnd() Dim code As Integer = proc.ExitCode If code = 0 Then StrBuilder.WrapMessage("Uninstall completed successfully.", "OK") Else StrBuilder.WrapMessage($"Uninstall failed with exit code {code}", "ERR") If Not String.IsNullOrWhiteSpace(errors) Then Console.WriteLine("[STDERR] " & errors) End If End If End Sub
排查与解决方向
- 注册表残留清理
Office卸载程序可能未完全删除Uninstall路径下的对应子键,导致系统误判产品状态。卸载完成后,检查对应注册表子键是否存在,若存在则通过代码(需管理员权限)删除该子键。 - 卸载参数补全
当前自动添加的/quiet和/norestart可能不足以完成彻底卸载,可尝试添加/uninstall <ProductID>明确指定卸载产品,或加入/force参数强制卸载,确保参数匹配Office官方卸载要求。 - 注册表视图兼容
代码仅使用RegistryView.Registry64,若系统为32位或Office是32位安装,需同时打开RegistryView.Registry32检查卸载信息,避免遗漏。 - 权限验证
卸载Office必须以管理员身份运行程序,可在程序清单中设置requestedExecutionLevel为requireAdministrator,或在代码中添加权限检查逻辑。 - 扩展产品ID范围
Microsoft 365包含多个关联组件,当前officeProductIds可能遗漏相关子键,可扩展数组加入MicrosoftTeamsRetail等其他Office相关ProductID。 - PowerShell命令转义修复
当installerArguments包含特殊字符时,PowerShell命令可能解析错误,可改用脚本块方式执行:Dim psCommand As String = $"& ""{fullPath}"" {installerArguments}; exit $LASTEXITCODE" Dim psi As New ProcessStartInfo("powershell.exe", $"-NoProfile -ExecutionPolicy Bypass -Command ""{psCommand}""")
内容的提问来源于stack exchange,提问作者Fusion Oz
相关产品推荐
相关产品推荐

