[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())
相关推荐
VidDown9 天前
VidDown 工具站:免费、本地优先的开发者工具箱
javascript·编辑器·音视频·视频编解码·视频
摇滚侠9 天前
IDEA 创建 Java 项目 手动整合 SSM 框架
java·ide·intellij-idea
霸道流氓气质9 天前
Trae IDE 新手入门指南
ide
VidDown10 天前
显卡处理视频技术详解:从硬解码到 NVENC,GPU 如何让视频处理起飞?
javascript·编辑器·音视频·视频编解码·视频
夜猫逐梦10 天前
【UE基础】03.蓝图与编辑器工作流
编辑器·ue·蓝图·ue编辑器
VidDown10 天前
视频帧率技术详解:从 24fps 到 120fps,帧率如何影响你的观看体验?
网络·网络协议·编辑器·音视频·视频编解码·视频
爱就是恒久忍耐10 天前
VSCode里如何比较2个branch
ide·vscode·编辑器
意法半导体STM3210 天前
【官方原创】如何为STM32CubeMX2配置Visual Studio Code配置方案
vscode·stm32·单片机·嵌入式硬件·策略模式·stm32cubemx·嵌入式开发
bloglin9999910 天前
vscode中可视化的合并分支,在“合并编辑器中解析”中“与基线进行比较”是什么意思
ide·vscode·编辑器
终将老去的穷苦程序员10 天前
IntelliJ IDEA 的安装教程
java·ide·intellij-idea