[vscode] vscode右键修复

我找了很久的问题,如何修改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())
相关推荐
玄月三初13 小时前
使用pandoc把word转换成markdown格式
vscode·word·markdown
533_14 小时前
[vscode] 禁止保存自动格式化
vscode
sz49723859916 小时前
vscode多种编译环境共存的方法
ide·vscode·stm32·编辑器·esp32
代数狂人17 小时前
《深入浅出Godot 4与C# 3D游戏开发》第二章:编辑器导航
3d·编辑器·游戏引擎·godot
DO_Community18 小时前
无封号焦虑!Claude Code 官方插件 +VS Code ,稳定接入的配置指南
人工智能·vscode·aigc·claude
不会编程的-程序猿19 小时前
PyCharm 直接把本地项目上传到 GitHub
ide·pycharm·github
克里斯蒂亚诺更新20 小时前
Android Studio创建一个新项目
android·ide·android studio
2501_9159184120 小时前
使用快蝎IDE进行iOS开发:从项目创建到真机调试全流程
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
一只积极向上的小咸鱼20 小时前
Vscode打开多个窗口
linux·运维·服务器·vscode