Windows 11 下 VSCode 右键菜单“通过 Code 打开”中文乱码:原因与修复

2518 字
13 分钟
Windows 11 下 VSCode 右键菜单“通过 Code 打开”中文乱码:原因与修复

作者:离尘
链接:https://www.zhihu.com/question/2019777857736455403/answer/2022865748335273444
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


0. 问题现象#

  • 环境:Windows 11 + VSCode 1.109+ + HiBit Uninstaller 4.x
  • 触发:使用 HiBit Uninstaller 执行注册表扫描(即使未点击清理)后,VSCode 右键菜单项“通过 Code 打开”显示为中文乱码,但功能正常。
  • 关键特征:
    • 仅在 Windows 11 复现,Windows 10 正常;
    • 与用户名(中文/英文)无关;
    • 卸载重装 VSCode 无效,只有用 HiBit 彻底清除残留后重装才能恢复。

1. 根本原因分析#

通过反复实验和注册表监控,定位到三个因素的叠加:

1.1 HiBit Uninstaller 的“副作用”#

该工具在执行注册表扫描时,会在 HKLM\SOFTWARE\Classes 下创建与 HKCU\Software\Classes 中同名且完全为空的项(例如 VSCodeContextMenu)。这一行为在旧版本(如 3.2.55)中就已存在。

1.2 VSCode 的版本变更#

VSCode 从 1.109 版本(2026年1月)开始,为适配 Windows 11 原生一级右键菜单,将右键菜单注册路径从旧的 HKCR\*\shell\VSCode 迁移至 HKCU\Software\Classes 区域。

1.3 Windows 11 的优先级策略#

传统上,HKCU 的优先级高于 HKLM,HKCR 是两者的合并视图。但在 Windows 11 中,对于 VSCode 这类外壳扩展,系统优先读取 HKLM 下的同名项。于是系统读到了 HiBit 创建的空项,无法获取显示文本,最终显示乱码。

结论:只要让 HKLM\SOFTWARE\Classes\VSCodeContextMenu 这个项非空,即可彻底解决。


2. 解决方案对比#

方案操作效果是否彻底
删除空项删除 HKLM 下的空 VSCodeContextMenu立即恢复,但下次扫描复现❌ 临时
写入 Title在空项中添加 Title 值系统读取到正确文字,HiBit 不会覆盖已有值的项✅ 彻底

3. 推荐方案:写入脚本(彻底修复)#

以下 PowerShell 脚本会自动提权,在 HKLM\SOFTWARE\Classes\VSCodeContextMenu 下创建 Title 值,内容为“通过 Code 打开”。

使用方法:

  1. 以管理员身份打开 PowerShell。
  2. 复制下方代码并粘贴执行。
  3. 重启文件资源管理器或注销重新登录。
Terminal window
<#
.SYNOPSIS
为 HKLM 下的 VSCodeContextMenu 添加 Title 值,解决右键菜单乱码问题。
.DESCRIPTION
此脚本仅在 HKLM\SOFTWARE\Classes\VSCodeContextMenu 下操作:
- 如果项不存在,则创建;
- 然后添加(或修改)名为 Title 的可扩充字符串值,数据为“通过 Code 打开”。
操作前自动提权,不备份注册表,但生成详细日志到桌面,便于排查问题。
.PRINCIPLE
问题根源:HiBit Uninstaller 在 HKLM 下创建了空的 VSCodeContextMenu 项,
而 Windows 11 优先读取 HKLM 下的配置,导致菜单显示乱码。
添加 Title 值后,HKLM 下的项有了有效数据,系统就能正常显示。
.NOTES
需要管理员权限。脚本会自动提权。
只操作指定项,不影响其他注册表位置。
#>
# ========== 自动提权 ==========
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
if (-not $isAdmin) {
$scriptPath = $MyInvocation.MyCommand.Path
if ($scriptPath) {
Write-Host "当前不是管理员权限,正在尝试以管理员身份重新启动..." -ForegroundColor Yellow
Start-Process PowerShell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`""
exit
} else {
Write-Host "错误:需要管理员权限才能运行此脚本。" -ForegroundColor Red
Write-Host "请关闭此窗口,然后右键点击 PowerShell 选择“以管理员身份运行”,再重新粘贴脚本。" -ForegroundColor Yellow
Read-Host "按回车键退出"
exit
}
}
# ========== 设置日志路径 ==========
$logDir = "$env:USERPROFILE\Desktop"
$logName = "AddVSCodeTitle_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$logFile = Join-Path $logDir $logName
# 日志写入函数
function Write-Log {
param([string]$Message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss.fff"
$logLine = "$timestamp - $Message"
Add-Content -Path $logFile -Value $logLine -Encoding UTF8
Write-Host $Message
}
# 初始化日志
Write-Log "========================================"
Write-Log "VSCode 右键菜单修复工具 (添加Title值) - 操作日志"
Write-Log "开始时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Log "========================================"
Write-Log "操作目标: HKLM\SOFTWARE\Classes\VSCodeContextMenu"
Write-Log "操作内容: 设置 Title = '通过 Code 打开' (类型: 可扩充字符串值)"
Write-Log ""
# ========== 定义路径 ==========
$regPath = "HKLM:\SOFTWARE\Classes\VSCodeContextMenu"
$valueName = "Title"
$valueData = "通过 Code 打开"
$valueType = "ExpandString"
# ========== 检查并创建项 ==========
Write-Log "[1] 检查目标项是否存在..."
if (-not (Test-Path $regPath)) {
Write-Log " 目标项不存在,正在创建..."
try {
New-Item -Path $regPath -Force -ErrorAction Stop | Out-Null
Write-Log " 创建成功。"
} catch {
Write-Log " 创建失败!错误信息: $_"
Write-Log " 请检查权限或路径是否正确。"
Write-Log "操作中止。"
Read-Host "按回车键退出"
exit 1
}
} else {
Write-Log " 目标项已存在。"
}
# ========== 记录当前状态(如果有Title值) ==========
try {
$currentValue = Get-ItemProperty -Path $regPath -Name $valueName -ErrorAction SilentlyContinue
if ($currentValue -and $currentValue.Title) {
Write-Log "[2] 当前 Title 值已存在,内容为: '$($currentValue.Title)'"
Write-Log " 将覆盖为新值。"
} else {
Write-Log "[2] 当前 Title 值不存在,将新建。"
}
} catch {
Write-Log "[2] 读取当前值失败(不影响后续操作): $_"
}
# ========== 设置 Title 值 ==========
Write-Log "[3] 正在设置 Title 值..."
try {
Set-ItemProperty -Path $regPath -Name $valueName -Value $valueData -Type $valueType -Force -ErrorAction Stop
Write-Log " 设置成功。"
} catch {
Write-Log " 设置失败!错误信息: $_"
Write-Log "操作中止。"
Read-Host "按回车键退出"
exit 1
}
# ========== 验证设置结果 ==========
Write-Log "[4] 验证设置结果..."
try {
$newValue = Get-ItemProperty -Path $regPath -Name $valueName -ErrorAction SilentlyContinue
if ($newValue -and $newValue.Title -eq $valueData) {
Write-Log " 验证通过,Title 值为: '$($newValue.Title)'"
} else {
Write-Log " 验证失败!当前值为: $($newValue.Title),期望为: '$valueData'"
Write-Log " 请手动检查注册表。"
}
} catch {
Write-Log " 验证时出错: $_"
}
# ========== 完成 ==========
Write-Log "========================================"
Write-Log "操作完成时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Log "日志文件保存至: $logFile"
Write-Log "========================================"
Write-Log ""
Write-Log "请重启文件资源管理器或注销重新登录以使更改生效。"
Read-Host "按回车键退出"

4. 备选方案:删除脚本(临时修复)#

如果你仍希望使用删除方式,可用以下脚本。它会自动删除 HKLM 下与 VSCode 相关的空项,并生成日志。

Terminal window
<#
.SYNOPSIS
自动删除由 HiBit Uninstaller 在 HKLM 下创建的、与 VSCode 相关的空注册表项。
.DESCRIPTION
此脚本扫描 HKLM\SOFTWARE\Classes 下与 HKCU\Software\Classes 同名且为空的项,
仅处理项名称中包含 "VSCode"(不区分大小写)的项,直接删除,无需用户确认。
操作前会自动提升管理员权限,并在用户下载目录下生成详细日志。
.PRINCIPLE
问题根源:HiBit Uninstaller 扫描时,会在 HKLM\SOFTWARE\Classes 下创建与 HKCU 中同名
的空项。系统读取右键菜单时,优先使用 HKLM 下的空项,导致显示异常。
删除这些空项后,系统回落到 HKCU 中的正确配置,右键菜单恢复正常。
此脚本只删除 VSCode 相关的空项,不影响其他软件。
.NOTES
需要管理员权限。脚本会自动提权。
#>
# ========== 自动提权 ==========
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
if (-not $isAdmin) {
$scriptPath = $MyInvocation.MyCommand.Path
if ($scriptPath) {
Write-Host "当前不是管理员权限,正在尝试以管理员身份重新启动..." -ForegroundColor Yellow
Start-Process PowerShell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`""
exit
} else {
Write-Host "错误:需要管理员权限才能运行此脚本。" -ForegroundColor Red
Write-Host "请关闭此窗口,然后右键点击 PowerShell 选择“以管理员身份运行”,再重新粘贴脚本。" -ForegroundColor Yellow
Read-Host "按回车键退出"
exit
}
}
# ========== 设置日志路径 ==========
$logDir = "$env:USERPROFILE\Downloads"
$logName = "FixVSCodeMenu_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$logFile = Join-Path $logDir $logName
# 写入日志头部
$logContent = @"
========================================
VSCode 右键菜单修复工具 - 操作日志
时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
脚本版本: 1.0
========================================
[原理]
HiBit Uninstaller 扫描注册表时,会在 HKLM\SOFTWARE\Classes 下创建与 HKCU\Software\Classes
中同名且为空的项。系统读取右键菜单时优先使用 HKLM 下的空项,导致显示异常。
本脚本删除这些与 VSCode 相关的空项,恢复正确的菜单显示。
[操作]
扫描并删除 HKLM\SOFTWARE\Classes 下与 HKCU\Software\Classes 同名且为空的项,
且项名称包含 "VSCode"(不区分大小写)。
无需用户确认,自动执行。
[执行结果]
"@
# 写入初始日志
$logContent | Out-File -FilePath $logFile -Encoding UTF8
# ========== 定义路径和关键词 ==========
$hkcuPath = "HKCU:\Software\Classes"
$hklmPath = "HKLM:\SOFTWARE\Classes"
$keyword = "VSCode"
# 扫描并删除
Write-Host "正在扫描注册表,请稍候..." -ForegroundColor Yellow
# 预加载 HKLM 所有子项名到哈希表(加速)
$hklmExistItems = @{}
if (Test-Path $hklmPath) {
Get-ChildItem $hklmPath -ErrorAction SilentlyContinue | ForEach-Object {
$hklmExistItems[$_.PSChildName] = $true
}
}
$deletedItems = @()
$failedItems = @()
if (Test-Path $hkcuPath) {
$hkcuNames = Get-ChildItem $hkcuPath | Select-Object -ExpandProperty PSChildName
foreach ($name in $hkcuNames) {
# 关键词过滤
if ($name -like "*$keyword*") {
if ($hklmExistItems.ContainsKey($name)) {
$hklmItem = Join-Path $hklmPath $name
$key = Get-Item $hklmItem -ErrorAction SilentlyContinue
if ($null -ne $key) {
$hasSubkeys = $key.GetSubKeyNames().Count -gt 0
$hasValues = $key.GetValueNames().Count -gt 0
if (-not $hasSubkeys -and -not $hasValues) {
try {
Remove-Item $hklmItem -Force -ErrorAction Stop
$deletedItems += $hklmItem
Write-Host "已删除: $hklmItem" -ForegroundColor Green
} catch {
$failedItems += "$hklmItem (错误: $($_.Exception.Message))"
Write-Host "删除失败: $hklmItem" -ForegroundColor Red
}
}
}
}
}
}
}
# 写入删除记录
$logContent = @"
`n[删除的项] (共 $($deletedItems.Count) 项)
"@
if ($deletedItems.Count -gt 0) {
$logContent += ($deletedItems | ForEach-Object { " $_" }) -join "`n"
} else {
$logContent += " 无"
}
$logContent += @"
`n[失败的项] (共 $($failedItems.Count) 项)
"@
if ($failedItems.Count -gt 0) {
$logContent += ($failedItems | ForEach-Object { " $_" }) -join "`n"
} else {
$logContent += " 无"
}
$logContent += @"
`n[完成时间] $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
========================================
"@
# 追加到日志文件
$logContent | Out-File -FilePath $logFile -Encoding UTF8 -Append
# 控制台输出
Write-Host "`n操作完成!" -ForegroundColor Green
Write-Host "成功删除 $($deletedItems.Count) 项,失败 $($failedItems.Count) 项。" -ForegroundColor Cyan
Write-Host "详细日志已保存至: $logFile" -ForegroundColor Yellow
Write-Host "请重启文件资源管理器或注销重新登录以使更改生效。" -ForegroundColor Cyan
Read-Host "按回车键退出"

5. 总结#

推荐使用写入脚本,一劳永逸,不受 HiBit 后续扫描影响。两个脚本均会自动提权、生成日志,安全可控。

该问题的本质是 HiBit Uninstaller 的“空项创建”行为与 Windows 11 新优先级策略的冲突。若其他软件未来也迁移至 HKCU 区域,同样可能触发此问题,排查思路可参考本文。

注:本文提到的两个脚本已在本地测试通过,如有任何问题欢迎评论区交流。

特别鸣谢:特别鸣谢 CSDN 社区 @Sponge_F 大佬在本问题的解决和推进上的支持和帮助,是他提供了解决思路才有了本篇文章!

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Windows 11 下 VSCode 右键菜单“通过 Code 打开”中文乱码:原因与修复
https://dongyue.org/posts/9/
作者
冬月
发布于
2026-09-10
许可协议
CC BY-SA 4.0

评论区

文章目录