[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())
相关推荐
F1FJJ10 小时前
Shield CLI Postgres v0.3.10:当 142 张表挤在一张 ER 图里,我们做了什么
网络·vscode·网络协议·postgresql·开源软件
小Tomkk13 小时前
怎么配置 Visual Studio Code 配置 C/C++
c语言·c++·vscode
逆向编程15 小时前
如何在Ubuntu虚拟机中使用Vim编辑器?
ubuntu·编辑器·vim
Risehuxyc15 小时前
Visual Studio 输出中文乱码问题
ide·visual studio
golang学习记15 小时前
VSCode 官宣:全新默认主题!
ide·vscode·编辑器
波尔德15 小时前
vscode codex 字体大小设置
ide·vscode·编辑器
qq_4275060817 小时前
vscode使用kimi code的简单经验分享
前端·vscode·ai编程
村中少年18 小时前
vscode如何添加ollama本地模型-实现token自由
vscode·llm·token·ollama·本地模型·qwen3
π同学18 小时前
ESP-IDF+vscode开发ESP32第四讲——I2C
vscode·esp32·i2c
kiki_241118 小时前
用IntelliJ IDEA编写Java程序,从0到1完整教程
java·ide·intellij-idea