[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())
相关推荐
荔枝吻1 小时前
【保姆级喂饭教程】Visual Studio 2026 中创建基于 c# 的 WinForms 入门教程
ide·c#·visual studio
2301_805962932 小时前
arduino IDE系列教程3:文件管理-侧边栏
ide
小圣贤君2 小时前
从「选中一段」到「整章润色」:编辑器里的 AI 润色是怎么做出来的
人工智能·electron·编辑器·vue3·ai写作·deepseek·写小说
贪嘴2 小时前
Visual Studio 2026 不支持 .net upgrade assistant 升级助手 安装失败怎么办
ide·.net·visual studio
2501_915909063 小时前
iOS 开发编译与真机调试流程的新思路,用快蝎 IDE 构建应用
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
安迪西嵌入式3 小时前
如何在VS Code中配置GCC编译器
vscode·gcc·mingw64·msys
2501_915106323 小时前
iOS 应用打包流程,不用 Xcode 生成安装包
ide·vscode·macos·ios·个人开发·xcode·敏捷流程
Filotimo_3 小时前
IDEA 更改快捷键关闭当前标签页
java·ide·intellij-idea
GJ_WL3 小时前
word自带公式编辑器自动将公式变成正体
编辑器·word