本文目录导读:

我来通过一个完整的Python案例,演示如何实现Windows右键菜单扩展。
使用注册表(简单方式)
为特定文件类型添加右键菜单
import winreg
import os
import sys
import json
class RightClickMenu:
def __init__(self):
self.script_path = sys.executable if getattr(sys, 'frozen', False) else __file__
def add_menu_for_txt(self, menu_name, python_script):
"""为.txt文件添加右键菜单"""
try:
# 打开.txt文件的注册表项
key_path = r"*\shell"
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, key_path, 0, winreg.KEY_SET_VALUE)
# 创建菜单项
menu_key = winreg.CreateKey(key, menu_name)
winreg.SetValue(menu_key, '', winreg.REG_SZ, menu_name)
# 设置命令
command_key = winreg.CreateKey(menu_key, 'command')
command = f'"{sys.executable}" "{python_script}" "%1"'
winreg.SetValue(command_key, '', winreg.REG_SZ, command)
winreg.CloseKey(command_key)
winreg.CloseKey(menu_key)
winreg.CloseKey(key)
print(f"成功添加 '{menu_name}' 右键菜单")
return True
except Exception as e:
print(f"添加右键菜单失败: {e}")
return False
def remove_menu(self, menu_name):
"""移除右键菜单"""
try:
key_path = r"*\shell"
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, key_path, 0, winreg.KEY_SET_VALUE)
winreg.DeleteKey(key, menu_name + "\\command")
winreg.DeleteKey(key, menu_name)
winreg.CloseKey(key)
print(f"成功移除 '{menu_name}' 右键菜单")
return True
except Exception as e:
print(f"移除右键菜单失败: {e}")
return False
# 右键菜单处理脚本示例
def txt_processor():
"""处理选中文件的脚本"""
import sys
if len(sys.argv) > 1:
file_path = sys.argv[1]
print(f"处理文件: {file_path}")
# 读取文件内容
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# 示例:统计文件信息
info = {
'文件名': os.path.basename(file_path),
'大小': f"{len(content)} 字符",
'行数': len(content.splitlines()),
'单词数': len(content.split())
}
print(json.dumps(info, ensure_ascii=False, indent=2))
except Exception as e:
print(f"处理文件失败: {e}")
if __name__ == "__main__":
# 使用示例
menu = RightClickMenu()
print("1. 添加右键菜单")
print("2. 移除右键菜单")
print("3. 处理文件测试")
choice = input("请选择操作: ")
if choice == '1':
menu_name = input("请输入菜单名称: ")
script_path = input("请输入Python脚本路径: ")
menu.add_menu_for_txt(menu_name, script_path)
elif choice == '2':
menu_name = input("请输入要移除的菜单名称: ")
menu.remove_menu(menu_name)
elif choice == '3':
txt_processor()
使用自定义类(高级方式)
import winreg
import os
import sys
import subprocess
from pathlib import Path
class AdvancedRightClickMenu:
"""高级右键菜单管理器"""
def __init__(self, app_name="MyPythonApp"):
self.app_name = app_name
self.registry_base = r"Software\Classes"
def add_menu_to_all_files(self, menu_text, icon_path="", command=""):
"""为所有文件添加右键菜单"""
base_key = winreg.HKEY_CLASSES_ROOT
shell_path = r"*\shell"
try:
# 打开或创建shell键
with winreg.OpenKey(base_key, shell_path, 0, winreg.KEY_SET_VALUE) as shell_key:
# 创建菜单项
with winreg.CreateKey(shell_key, self.app_name) as app_key:
# 设置菜单显示文本
winreg.SetValueEx(app_key, "", 0, winreg.REG_SZ, menu_text)
# 设置图标(可选)
if icon_path:
winreg.SetValueEx(app_key, "Icon", 0, winreg.REG_SZ, icon_path)
# 设置扩展验证
winreg.SetValueEx(app_key, "AppliesTo", 0, winreg.REG_SZ, "System.FileName")
# 创建命令键
with winreg.CreateKey(app_key, "command") as cmd_key:
if command:
cmd = f'"{sys.executable}" "{command}" "%1"'
else:
# 使用当前脚本
cmd = f'"{sys.executable}" "{__file__}" "%1"'
winreg.SetValueEx(cmd_key, "", 0, winreg.REG_SZ, cmd)
print(f"成功添加右键菜单: {menu_text}")
return True
except Exception as e:
print(f"添加菜单失败: {e}")
return False
def add_menu_to_folder(self, menu_text, command=""):
"""为文件夹添加右键菜单"""
base_key = winreg.HKEY_CLASSES_ROOT
shell_path = r"Directory\shell"
try:
with winreg.OpenKey(base_key, shell_path, 0, winreg.KEY_SET_VALUE) as shell_key:
with winreg.CreateKey(shell_key, self.app_name) as app_key:
winreg.SetValueEx(app_key, "", 0, winreg.REG_SZ, menu_text)
with winreg.CreateKey(app_key, "command") as cmd_key:
if command:
cmd = f'"{sys.executable}" "{command}" "%1"'
else:
cmd = f'"{sys.executable}" "{__file__}" "%1"'
winreg.SetValueEx(cmd_key, "", 0, winreg.REG_SZ, cmd)
print(f"成功添加文件夹右键菜单: {menu_text}")
return True
except Exception as e:
print(f"添加菜单失败: {e}")
return False
def add_submenu(self, menu_text, submenu_items):
"""添加子菜单(多级菜单)"""
base_key = winreg.HKEY_CLASSES_ROOT
shell_path = r"*\shell"
try:
with winreg.OpenKey(base_key, shell_path, 0, winreg.KEY_SET_VALUE) as shell_key:
with winreg.CreateKey(shell_key, self.app_name) as app_key:
winreg.SetValueEx(app_key, "", 0, winreg.REG_SZ, menu_text)
winreg.SetValueEx(app_key, "SubCommands", 0, winreg.REG_SZ, "")
winreg.SetValueEx(app_key, "MUIVerb", 0, winreg.REG_SZ, menu_text)
# 创建子菜单项
for i, (sub_text, sub_cmd) in enumerate(submenu_items, 1):
sub_key_name = f"{self.app_name}\\shell\\item{i}"
with winreg.CreateKey(base_key, sub_key_name) as sub_key:
winreg.SetValueEx(sub_key, "MUIVerb", 0, winreg.REG_SZ, sub_text)
with winreg.CreateKey(sub_key, "command") as cmd_key:
cmd = f'"{sys.executable}" "{sub_cmd}" "%1"'
winreg.SetValueEx(cmd_key, "", 0, winreg.REG_SZ, cmd)
print(f"成功添加子菜单: {menu_text}")
return True
except Exception as e:
print(f"添加子菜单失败: {e}")
return False
def remove_menu(self):
"""移除右键菜单"""
paths = [
f"*\\shell\\{self.app_name}",
f"Directory\\shell\\{self.app_name}",
f"*\\shell\\{self.app_name}\\shell",
]
base_key = winreg.HKEY_CLASSES_ROOT
for path in paths:
try:
# 递归删除子键
self._delete_key_recursive(base_key, path)
except:
pass
print(f"成功移除右键菜单: {self.app_name}")
def _delete_key_recursive(self, base_key, key_path):
"""递归删除注册表键"""
try:
with winreg.OpenKey(base_key, key_path, 0, winreg.KEY_READ) as key:
# 获取子键列表
i = 0
while True:
try:
sub_key = winreg.EnumKey(key, i)
self._delete_key_recursive(base_key, f"{key_path}\\{sub_key}")
i += 1
except WindowsError:
break
winreg.DeleteKey(base_key, key_path)
except Exception:
pass
# 实际处理脚本
class FileProcessor:
"""文件处理器示例"""
@staticmethod
def analyze_file(file_path):
"""分析文件"""
if not os.path.exists(file_path):
return {"error": "文件不存在"}
file_size = os.path.getsize(file_path)
file_ext = os.path.splitext(file_path)[1]
file_name = os.path.basename(file_path)
result = {
"文件名": file_name,
"扩展名": file_ext,
"大小": f"{file_size / 1024:.2f} KB",
"路径": file_path
}
# 如果是文本文件,读取内容
if file_ext in ['.txt', '.py', '.md', '.json', '.xml', '.html', '.css', '.js']:
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
result.update({
"字符数": len(content),
"行数": len(content.splitlines()),
"单词数": len(content.split())
})
except:
result["编码"] = "无法读取"
return result
@staticmethod
def backup_file(file_path):
"""备份文件"""
if os.path.exists(file_path):
backup_path = file_path + ".backup"
import shutil
shutil.copy2(file_path, backup_path)
return {"success": True, "backup_path": backup_path}
return {"success": False, "error": "源文件不存在"}
def main():
"""主入口"""
import sys
if len(sys.argv) > 1:
file_path = sys.argv[1]
processor = FileProcessor()
# 分析文件
info = processor.analyze_file(file_path)
print("文件分析结果:")
for key, value in info.items():
print(f"{key}: {value}")
else:
# 管理界面
menu = AdvancedRightClickMenu("PythonTools")
print("右键菜单管理器")
print("=" * 30)
print("1. 为所有文件添加 '文件分析' 菜单")
print("2. 为文件夹添加 '文件夹分析' 菜单")
print("3. 添加子菜单(分析/备份)")
print("4. 移除所有菜单")
print("5. 退出")
choice = input("请选择 (1-5): ")
if choice == '1':
# 添加文件分析菜单
menu.add_menu_to_all_files("Python 文件分析")
elif choice == '2':
# 添加文件夹菜单
menu.add_menu_to_folder("Python 文件夹分析")
elif choice == '3':
# 添加子菜单
submenu_items = [
("分析文件", __file__),
("备份文件", __file__)
]
menu.add_submenu("Python 工具", submenu_items)
elif choice == '4':
# 移除菜单
menu.remove_menu()
elif choice == '5':
print("退出程序")
sys.exit(0)
if __name__ == "__main__":
main()
使用 pywin32(最完整)
import win32con
import win32api
import win32security
import pythoncom
import sys
import os
class ContextMenuHandler:
"""Windows右键菜单COM组件"""
def __init__(self):
self._reg_clsid = "{YOUR_GUID}" # 需要生成GUID
self._reg_progid = "PythonContextMenu"
self._reg_desc = "Python Context Menu Handler"
def register(self):
"""注册COM组件"""
import win32com.server.register
win32com.server.register.UseCommandLine(
self._reg_clsid,
self._reg_progid,
self._reg_desc,
"PythonContextMenu.ContextMenu"
)
def unregister(self):
"""注销COM组件"""
import win32com.server.unregister
win32com.server.unregister.UseCommandLine(
self._reg_clsid,
self._reg_progid
)
# 实际右键菜单处理
def handle_right_click():
"""处理右键点击事件"""
import sys
if len(sys.argv) > 1:
selected_files = sys.argv[1:]
print("选中的文件:")
for file in selected_files:
print(f" - {file}")
# 在这里添加你的处理逻辑
# 批量重命名、压缩、加密等
if __name__ == "__main__":
# 检查是否传递了文件参数
if len(sys.argv) > 1:
handle_right_click()
else:
# 注册/注销菜单
handler = ContextMenuHandler()
print("1. 注册右键菜单")
print("2. 注销右键菜单")
choice = input("请选择: ")
if choice == '1':
handler.register()
print("右键菜单已注册")
elif choice == '2':
handler.unregister()
print("右键菜单已注销")
使用示例
创建处理脚本 process_files.py
import sys
import os
import json
from datetime import datetime
def process_selected_file(file_path):
"""处理选中的文件"""
print(f"""
==================== 文件处理结果 ====================
文件路径: {file_path}
处理时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
=================================================
""")
# 获取文件信息
if os.path.exists(file_path):
stat = os.stat(file_path)
info = {
"文件大小": f"{stat.st_size / 1024:.2f} KB",
"创建时间": datetime.fromtimestamp(stat.st_ctime).strftime('%Y-%m-%d %H:%M:%S'),
"修改时间": datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M:%S'),
"访问时间": datetime.fromtimestamp(stat.st_atime).strftime('%Y-%m-%d %H:%M:%S')
}
print("文件信息:")
for key, value in info.items():
print(f" {key}: {value}")
# 如果是文本文件,添加内容分析
if file_path.endswith(('.txt', '.py', '.md', '.log')):
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
print(f"\n文本分析:")
print(f" 字符数: {len(content)}")
print(f" 行数: {len(content.splitlines())}")
except:
print("\n无法读取文件内容")
if __name__ == "__main__":
if len(sys.argv) > 1:
file_path = sys.argv[1]
process_selected_file(file_path)
else:
print("请右键点击文件,然后选择此程序")
安装脚本 install_menu.py
import winreg
import sys
import os
def install_right_click_menu():
"""安装右键菜单"""
script_path = os.path.abspath("process_files.py")
menu_name = "Python 文件分析"
try:
# 为所有文件添加菜单
key_path = r"*\shell"
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, key_path, 0, winreg.KEY_SET_VALUE)
# 创建菜单项
menu_key = winreg.CreateKey(key, menu_name)
winreg.SetValue(menu_key, '', winreg.REG_SZ, menu_name)
# 设置命令
command_key = winreg.CreateKey(menu_key, 'command')
command = f'"{sys.executable}" "{script_path}" "%1"'
winreg.SetValue(command_key, '', winreg.REG_SZ, command)
winreg.CloseKey(command_key)
winreg.CloseKey(menu_key)
winreg.CloseKey(key)
print(f"✓ 右键菜单 '{menu_name}' 安装成功!")
print(f" 执行脚本: {script_path}")
except Exception as e:
print(f"✗ 安装失败: {e}")
sys.exit(1)
def uninstall_right_click_menu():
"""卸载右键菜单"""
menu_name = "Python 文件分析"
try:
key_path = r"*\shell"
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, key_path, 0, winreg.KEY_SET_VALUE)
# 删除命令子键和菜单主键
try:
winreg.DeleteKey(key, menu_name + "\\command")
winreg.DeleteKey(key, menu_name)
except:
pass # 键可能已经不存在
winreg.CloseKey(key)
print(f"✓ 右键菜单 '{menu_name}' 已卸载")
except Exception as e:
print(f"✗ 卸载失败: {e}")
sys.exit(1)
if __name__ == "__main__":
print("右键菜单安装工具")
print("=" * 30)
print("1. 安装右键菜单")
print("2. 卸载右键菜单")
choice = input("请选择 (1-2): ")
if choice == '1':
install_right_click_menu()
elif choice == '2':
uninstall_right_click_menu()
else:
print("无效选择")
注意事项
- 管理员权限:修改注册表需要管理员权限
- 安全考虑:不要添加恶意功能
- 测试环境:先在测试环境验证
- 备份注册表:修改前备份
- GUID生成:使用COM组件时需要唯一GUID
这些示例涵盖了不同复杂度的右键菜单实现,你可以根据需求选择合适的方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播