VMware Workstation Pro 卸载失败:安装向导提前结束、错误 1603 的排查与解决

环境:Windows 11、VMware Workstation Pro 17.6.4。本文记录一次真实卸载故障:通过日志定位到虚拟网络注册表权限异常,修复后成功卸载。

适用范围:卸载日志停在 VM_UninstallNetworking,且 VMware 日志出现 VMnetBridge 权限异常。其他原因引起的 1603,需要另行排查。

一、问题现象

卸载 VMware Workstation Pro 时,向导弹出:

text 复制代码
VMware Workstation 安装向导提前结束

由于发生错误,VMware Workstation Pro 安装向导提前结束。
您的系统尚未修改。

明明在卸载,为什么提示"安装向导"?因为安装、修改和卸载共用 Windows Installer 安装包及相关向导。这段提示只能说明操作失败,无法直接指出原因。

本次故障中,没有正在运行的虚拟机进程;以管理员身份执行卸载,仍然返回错误 1603。

二、先看日志,1603 只是结果

1603 是 Windows Installer 的通用失败代码,不能仅凭这个数字判断故障原因。需要结合失败步骤和组件日志定位。

1. 找到安装记录和产品代码

在 PowerShell 中查询卸载注册表,避免使用可能触发 MSI 一致性检查的 Win32_Product:

powershell 复制代码
$paths = @(
    'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
    'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)

Get-ItemProperty $paths -ErrorAction SilentlyContinue |
    Where-Object { $_.DisplayName -match 'VMware Workstation' } |
    Select-Object DisplayName, DisplayVersion, PSChildName,
        UninstallString, InstallSource

本机查到的版本为 17.6.4,产品代码为:

text 复制代码
{6EC7759F-B700-4743-BB65-BD3ED905D545}

产品代码来自本机安装记录,不同版本或安装包可能不同,不要直接套用。

2. 生成详细卸载日志

关闭 VMware 和虚拟机,在"以管理员身份运行"的 PowerShell 中执行:

powershell 复制代码
# 替换为你查到的产品代码
$productCode = '{6EC7759F-B700-4743-BB65-BD3ED905D545}'
$logPath = Join-Path $env:TEMP 'vmware-uninstall.log'

$arguments = '/x {0} /qn /norestart /L*v "{1}"' -f $productCode, $logPath
$process = Start-Process msiexec.exe -ArgumentList $arguments -Wait -PassThru
$process.ExitCode

参数含义:

参数 用途
/x 卸载指定产品
/qn 静默执行,不显示安装界面
/norestart 不自动重启电脑
/L*v 输出详细日志

本次日志中的关键内容是:

text 复制代码
CustomAction VM_UninstallNetworking returned actual error code 1603

失败点明确落在 VM_UninstallNetworking,也就是 VMware 虚拟网络组件的卸载步骤。

中文系统的 MSI 日志可能使用"返回值 3",英文日志中通常为 Return value 3。搜索这些标记并查看前面的内容,有助于找到失败操作。

3. 查看 VMware 组件日志

本次 VMware 的详细日志位于当前用户临时目录:

powershell 复制代码
Select-String -Path "$env:TEMP\vminst.log" `
    -Pattern 'VNLCopyBridgeConfiguration', 'bogus', 'VMnetBridge' |
    Select-Object -Last 20

关键警告指向 VMnetLib\VMnetBridge,并包含:

text 复制代码
permissions ... appear to be bogus

这比单独一个 1603 更有价值:它把排查范围缩小到了 VMware 虚拟网络配置的注册表访问权限。

如果当前临时目录没有该文件,应结合实际运行账户、日志时间和安装程序输出寻找,不能把旧日志当作本次故障证据。

三、根因:32 位注册表视图中的权限异常

64 位 Windows 同时提供 32 位和 64 位注册表视图。同样的逻辑路径:

text 复制代码
HKLM\SOFTWARE\VMware, Inc.\VMnetLib

在不同视图下可以对应不同的配置。32 位视图通常可在注册表编辑器中通过以下路径看到:

text 复制代码
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\VMware, Inc.\VMnetLib

本次排查先处理了 64 位视图,卸载仍然失败。随后通过 .NET 注册表 API 显式检查两个视图,才发现 32 位视图中的 VMnetBridge 权限异常。

该项的访问规则只保留了当前用户的一条受限授权,缺少供系统账户和管理员组使用的显式完整控制规则。修复这一视图后,卸载程序顺利通过了此前失败的网络清理步骤。

因此,本次故障可以确认的直接阻塞点是相关注册表权限。至于权限最初由什么操作或程序改变,现有日志无法确定。

四、解决方案:备份配置,修复权限,再正常卸载

下面给出根据本次排查整理的修复示例。它只处理日志指向的 32 位 VMware 网络配置项,不要用于没有相同日志证据的其他故障。

1. 备份两个注册表视图

在管理员 PowerShell 中执行:

powershell 复制代码
$backupDir = Join-Path $env:TEMP (
    'VMware-Uninstall-Backup-' + (Get-Date -Format 'yyyyMMdd-HHmmss')
)
New-Item -ItemType Directory -Path $backupDir -Force | Out-Null

& reg.exe export 'HKLM\SOFTWARE\VMware, Inc.\VMnetLib' `
    (Join-Path $backupDir 'VMnetLib-32.reg') /y /reg:32

& reg.exe export 'HKLM\SOFTWARE\VMware, Inc.\VMnetLib' `
    (Join-Path $backupDir 'VMnetLib-64.reg') /y /reg:64

.reg 导出保存键和值,不保存访问权限。下面的脚本还会单独保存修改前的权限描述符。

2. 显式打开 32 位视图并修复访问规则

继续在同一个管理员 PowerShell 窗口中执行:

powershell 复制代码
$ErrorActionPreference = 'Stop'

$subKeys = @(
    'SOFTWARE\VMware, Inc.\VMnetLib'
    'SOFTWARE\VMware, Inc.\VMnetLib\VMnetBridge'
)

$root = [Microsoft.Win32.RegistryKey]::OpenBaseKey(
    [Microsoft.Win32.RegistryHive]::LocalMachine,
    [Microsoft.Win32.RegistryView]::Registry32
)

try {
    foreach ($subKey in $subKeys) {
        $key = $root.OpenSubKey(
            $subKey,
            [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
            [System.Security.AccessControl.RegistryRights]::ReadPermissions -bor
            [System.Security.AccessControl.RegistryRights]::ChangePermissions
        )

        if ($null -eq $key) {
            throw "注册表项不存在:$subKey;请重新核对日志与注册表视图。"
        }

        try {
            $acl = $key.GetAccessControl()

            # 单独备份原权限描述符;.reg 文件不包含权限。
            $sddl = $acl.GetSecurityDescriptorSddlForm(
                [System.Security.AccessControl.AccessControlSections]::Access
            )
            [pscustomobject]@{
                View = 'Registry32'
                Key  = $subKey
                Dacl = $sddl
            } | ConvertTo-Json -Compress |
                Add-Content -Path (Join-Path $backupDir 'permissions.jsonl')

            # 使用 SID,避免不同 Windows 显示语言造成账户名称不匹配。
            foreach ($sidText in @('S-1-5-18', 'S-1-5-32-544')) {
                $sid = [System.Security.Principal.SecurityIdentifier]::new($sidText)
                $rule = [System.Security.AccessControl.RegistryAccessRule]::new(
                    $sid,
                    [System.Security.AccessControl.RegistryRights]::FullControl,
                    [System.Security.AccessControl.InheritanceFlags]::ContainerInherit,
                    [System.Security.AccessControl.PropagationFlags]::None,
                    [System.Security.AccessControl.AccessControlType]::Allow
                )
                $acl.SetAccessRule($rule)
            }

            $key.SetAccessControl($acl)
            Write-Host "已修复:Registry32\$subKey"
        }
        finally {
            $key.Dispose()
        }
    }
}
finally {
    $root.Dispose()
}

两个 SID 的含义是:

SID 账户或组
S-1-5-18 本地系统账户 SYSTEM
S-1-5-32-544 本地 Administrators 管理员组

脚本补充这两个主体的完整控制权限,并保留其他现有规则。如果执行时报"拒绝访问",应继续检查该键的所有者和拒绝规则,不要直接对整个注册表批量修改权限。

3. 重新卸载并检查返回码

重新执行前面的 msiexec /x 命令,建议使用新的日志文件名。

本次实际卸载最终返回:

text 复制代码
UninstallExitCode=0
MainEngineThread is returning 0

说明 Windows Installer 已成功完成卸载。如果返回 3010,则表示操作成功,但需要重启;是否重启以实际结果为准。

五、如何确认已经卸载成功

除了查看成功返回码,还应核对安装记录和实际文件:

powershell 复制代码
Get-ItemProperty $paths -ErrorAction SilentlyContinue |
    Where-Object { $_.DisplayName -match 'VMware Workstation' } |
    Select-Object DisplayName, DisplayVersion

# 替换为自己的原安装路径
Test-Path -LiteralPath 'E:\vmware\vmware.exe'

Get-Service -ErrorAction SilentlyContinue |
    Where-Object { $_.DisplayName -match 'VMware' } |
    Select-Object Name, Status

本机验证结果:

  • VMware Workstation 安装记录已消失。
  • 原路径下的 vmware.exe 已移除。
  • 此前发现的 VMware 相关服务已移除。
  • 未手动删除虚拟机目录,虚拟机文件保留。

如果电脑还安装了其他 VMware 产品,仍有 VMware 服务不一定代表 Workstation 卸载失败,应核对服务所属产品。

六、这次排查的几个经验

  1. 先找失败步骤。 1603 范围太大,VM_UninstallNetworking 才能指明排查方向。
  2. 管理员权限不等于目标项权限正常。 提升运行权限无法自动修复注册表中已有的异常访问规则。
  3. 明确注册表视图。 只看 64 位视图,可能漏掉实际被组件访问的 32 位配置。
  4. 修复后走正常卸载流程。 直接删除安装目录可能留下驱动、服务和安装记录。
  5. 成功要有证据。 返回码、安装记录、主程序文件和相关服务共同验证,比只看向导关闭更可靠。

本次的故障链路是:32 位 VMware 网络配置权限异常 → 虚拟网络卸载动作失败 → MSI 返回 1603 → 向导提前结束。修复对应权限后,正常卸载流程即可完成。

参考资料

该资料用于理解 1603 与权限故障的关系;本文对 VMnetBridge 和注册表视图的判断依据为本机实际卸载日志与修复结果。

相关推荐
User_芊芊君子1 小时前
【JavaEE初阶 - 网络原理】网络分几层?从自定义协议聊到 DNS
java·网络·java-ee
聚美智数8 小时前
智能结构化识别-图片结构解析-图像结构化解析-照片结构化解析
android·java·数据库
十年Java程序媛8 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
我是人✓9 小时前
SpringBoot静态资源映射揭秘
java·spring boot·后端
土豆.exe9 小时前
nf_tables 的 verdict 被读了两次:一个十年未闭合的位域错配
java·数据库·网络安全·缓存
小坏讲微服务10 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
kunicoding11 小时前
多线程编程核心概念详解:从线程基础到并发安全
java·jvm·安全
snow@li11 小时前
SpringBoot:核心注解全景梳理 / @xxx 叫“注解”(Annotation)
java·spring
devilnumber11 小时前
避坑_IDEA 提取方法(Extract Method)工具
java·ide·intellij-idea