我找了很久的问题,如何修改vscode右键菜单丢失的问题,
很多都是自己手动调节, 这样很费劲, 我不是很喜欢, 现在编写一个脚本来快速完成此问题, 从而避免手动操作带来的错误
下方为对应的代码
python
#!/usr/bin/env python3
"""
Diagnose and repair VS Code context menu entries on Windows.
Use cases:
1) Check whether "Open with Code" exists for folder background right-click.
2) Repair missing/broken entries by writing per-user registry keys.
This script writes to HKCU\\Software\\Classes so admin rights are usually not required.
修复 Windows 上 VS Code 右键菜单项的诊断和修复。
"""
from __future__ import annotations
import os
import platform
import sys
from dataclasses import dataclass
from typing import List, Optional, Tuple
try:
import winreg
except ImportError as exc:
raise SystemExit("This script only supports Windows (winreg is unavailable).") from exc
MENU_NAME = "VSCode"
MENU_TEXT = "Open with Code"
@dataclass
class CheckItem:
key_path: str
exists: bool
menu_text: Optional[str]
command: Optional[str]
issue: Optional[str] = None
def is_windows() -> bool:
return platform.system().lower() == "windows"
def candidate_code_paths() -> List[str]:
local = os.environ.get("LOCALAPPDATA", "")
program_files = os.environ.get("ProgramFiles", "")
program_files_x86 = os.environ.get("ProgramFiles(x86)", "")
candidates = [
os.path.join(local, "Programs", "Microsoft VS Code", "Code.exe"),
os.path.join(program_files, "Microsoft VS Code", "Code.exe"),
os.path.join(program_files_x86, "Microsoft VS Code", "Code.exe"),
]
# Keep order, remove empty/duplicates.
seen = set()
ordered = []
for path in candidates:
norm = os.path.normcase(path)
if path and norm not in seen:
seen.add(norm)
ordered.append(path)
return ordered
def get_code_path_from_app_paths() -> Optional[str]:
app_paths_subkey = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Code.exe"
for root in (winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE):
try:
with winreg.OpenKey(root, app_paths_subkey, 0, winreg.KEY_READ) as key:
value, _ = winreg.QueryValueEx(key, "")
if value and os.path.exists(value):
return value
except FileNotFoundError:
continue
except OSError:
continue
return None
def resolve_code_exe() -> Optional[str]:
from_registry = get_code_path_from_app_paths()
if from_registry:
return from_registry
for path in candidate_code_paths():
if os.path.exists(path):
return path
return None
def read_string_value(root, path: str, value_name: str = "") -> Optional[str]:
try:
with winreg.OpenKey(root, path, 0, winreg.KEY_READ) as key:
value, _ = winreg.QueryValueEx(key, value_name)
return str(value)
except FileNotFoundError:
return None
except OSError:
return None
def check_menu_key(menu_key_path: str) -> CheckItem:
menu_text = read_string_value(winreg.HKEY_CURRENT_USER, menu_key_path, "")
command_path = menu_key_path + r"\command"
command = read_string_value(winreg.HKEY_CURRENT_USER, command_path, "")
exists = menu_text is not None or command is not None
issue = None
if not exists:
issue = "Missing key"
elif not command:
issue = "Missing command value"
elif "Code.exe" not in command and "code.exe" not in command:
issue = "Command does not point to Code.exe"
return CheckItem(
key_path=menu_key_path,
exists=exists,
menu_text=menu_text,
command=command,
issue=issue,
)
def check_configuration() -> List[CheckItem]:
base = r"Software\Classes"
checks = [
check_menu_key(base + "\\Directory\\Background\\shell\\" + MENU_NAME),
check_menu_key(base + "\\Directory\\shell\\" + MENU_NAME),
]
return checks
def create_or_update_menu(root, menu_key_path: str, menu_text: str, icon_path: str, command_value: str) -> None:
with winreg.CreateKeyEx(root, menu_key_path, 0, winreg.KEY_SET_VALUE) as menu_key:
winreg.SetValueEx(menu_key, "", 0, winreg.REG_SZ, menu_text)
winreg.SetValueEx(menu_key, "Icon", 0, winreg.REG_SZ, icon_path)
with winreg.CreateKeyEx(root, menu_key_path + r"\command", 0, winreg.KEY_SET_VALUE) as cmd_key:
winreg.SetValueEx(cmd_key, "", 0, winreg.REG_SZ, command_value)
def fix_configuration(code_exe: str) -> Tuple[bool, List[str]]:
messages = []
root = winreg.HKEY_CURRENT_USER
base = r"Software\Classes"
bg_menu = base + "\\Directory\\Background\\shell\\" + MENU_NAME
dir_menu = base + "\\Directory\\shell\\" + MENU_NAME
bg_cmd = f'"{code_exe}" "%V"'
dir_cmd = f'"{code_exe}" "%1"'
try:
create_or_update_menu(root, bg_menu, MENU_TEXT, code_exe, bg_cmd)
messages.append(f"Updated: HKCU\\{bg_menu}")
create_or_update_menu(root, dir_menu, MENU_TEXT, code_exe, dir_cmd)
messages.append(f"Updated: HKCU\\{dir_menu}")
return True, messages
except PermissionError:
messages.append("Permission denied when writing registry keys.")
return False, messages
except OSError as exc:
messages.append(f"Registry write failed: {exc}")
return False, messages
def print_check_report(items: List[CheckItem], code_exe: Optional[str]) -> bool:
print("== VS Code Context Menu Check ==")
print(f"OS: {platform.platform()}")
print(f"Detected Code.exe: {code_exe or 'NOT FOUND'}")
print()
all_ok = True
for item in items:
status = "OK"
if item.issue:
status = "ISSUE"
all_ok = False
print(f"[{status}] {item.key_path}")
print(f" Menu Text: {item.menu_text!r}")
print(f" Command : {item.command!r}")
if item.issue:
print(f" Problem : {item.issue}")
print()
return all_ok
def main() -> int:
if not is_windows():
print("This script only supports Windows.")
return 2
code_exe = resolve_code_exe()
check_items = check_configuration()
all_ok = print_check_report(check_items, code_exe)
if all_ok:
print("No issues found.")
return 0
print("Issues detected. Starting automatic repair...")
if not code_exe:
print("Cannot fix because Code.exe was not found.")
print("Please install VS Code first, then run this script again.")
return 3
print("Applying fixes...")
ok, messages = fix_configuration(code_exe)
for msg in messages:
print(f"- {msg}")
if not ok:
return 4
print("Repair completed. Re-checking...")
verify_items = check_configuration()
verify_ok = print_check_report(verify_items, code_exe)
if verify_ok:
print("Context menu repair succeeded.")
print("If Explorer does not update immediately, restart Explorer or sign out/in.")
return 0
print("Repair attempted, but some issues remain.")
return 5
if __name__ == "__main__":
sys.exit(main())