如何通过Windows10右键菜单向单exe传多文件并制作自动加注册表的安装包
解决方案
1. 选中多文件仅启动单个exe实例的实现方法
默认直接在HKEY_CLASSES_ROOT\*\shell\下添加的右键条目,每选中一个文件就会触发一次命令调用,所以会启动多个exe实例,可通过单实例互斥+进程间通信的方案解决,开发成本最低:
- 首先给你的Python脚本增加命名互斥量检测逻辑,首次启动时创建全局唯一命名的互斥量,后续启动检测到互斥量已存在时,就将本次收到的文件路径通过命名管道、WM_COPYDATA消息等方式传递给已运行的实例,随后自身直接退出。
- 首次启动的主实例增加监听逻辑,收集所有后续实例传递过来的文件路径,待所有选中文件对应的进程都完成参数传递后,统一执行处理逻辑。
Python 实现互斥量检测的示例代码:
import sys import win32event import win32api from winerror import ERROR_ALREADY_EXISTS # 替换为你自己的全局唯一互斥量名称 MUTEX_NAME = "MY_APP_UNIQUE_MUTEX_123456" mutex = win32event.CreateMutex(None, False, MUTEX_NAME) if win32api.GetLastError() == ERROR_ALREADY_EXISTS: # 已有实例运行,将当前参数传递给已有实例后退出 send_file_paths_to_running_instance(sys.argv[1:]) sys.exit(0) # 以下为主实例的正常逻辑,增加参数监听接收逻辑即可
如果不想自己实现进程间通信,也可以借助系统的Send To菜单逻辑,将exe快捷方式放到shell:sendto目录下,选中多文件后通过发送到菜单调用,默认会将所有选中文件路径作为参数传递给同一个exe实例,不需要修改代码,只是入口会放在发送到二级菜单里。
2. 自动添加右键菜单的安装包制作方法
两种常用方案可选:
方案1:使用Inno Setup制作安装包
Inno Setup是免费的Windows安装包制作工具,直接在配置脚本的[Registry]段声明需要写入的注册表项即可,卸载时会自动删除对应注册表:
[Setup] AppName=我的工具 AppVersion=1.0 DefaultDirName={pf}\我的工具 OutputDir=输出目录 OutputBaseFilename=我的工具安装包 [Files] Source: "你的exe路径\myapp.exe"; DestDir: "{app}"; Flags: ignoreversion [Registry] Root: HKCR; Subkey: "*\shell\MY_APP"; ValueType: string; ValueName: ""; ValueData: "使用我的工具处理"; Flags: uninsdeletekey Root: HKCR; Subkey: "*\shell\MY_APP\command"; ValueType: string; ValueName: ""; ValueData: """{app}\myapp.exe"" ""%1"""
编译后生成的安装包即可实现安装时自动注册右键菜单,卸载时自动清理。
方案2:内置注册/卸载功能
直接在Python脚本中增加命令行参数,提供--register和--unregister功能,运行时自动操作注册表,不需要额外的安装包制作工具:
import sys import winreg def register_menu(): exe_path = sys.executable key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, r"*\shell\MY_APP\command") winreg.SetValueEx(key, "", 0, winreg.REG_SZ, f'"{exe_path}" "%1"') winreg.CloseKey(key) print("右键菜单注册成功") def unregister_menu(): winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, r"*\shell\MY_APP\command") winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, r"*\shell\MY_APP") print("右键菜单卸载成功") if __name__ == "__main__": if "--register" in sys.argv: register_menu() sys.exit(0) if "--unregister" in sys.argv: unregister_menu() sys.exit(0) # 原有业务逻辑
运行该功能时需要管理员权限,打包后用户只需以管理员身份运行myapp.exe --register即可完成右键菜单注册。
内容的提问来源于stack exchange,提问作者Vijay Motwani
相关产品推荐
相关产品推荐

