如何阻止多人在共享驱动器上同时运行同一Windows EXE程序
解决共享驱动器上EXE多用户同时运行的问题
你考虑的隐藏文件方案确实有坑——万一用户强制终止程序(比如Ctrl+C),残留的文件会直接导致后续无法启动。我给你推荐文件独占锁的方案,这是Windows环境下最可靠的方式:程序运行时给一个锁文件加独占锁,不管是正常退出还是异常崩溃,系统都会自动释放锁,完全不会有残留问题。
下面给你两种可直接用的实现方式,都是Python代码,打包成EXE后就能生效:
方案一:原生Windows API实现(无需额外依赖)
不用装第三方库,直接用Windows自带的API创建独占锁。原理是:尝试以拒绝共享的模式打开一个隐藏锁文件,如果打开失败,说明已有实例在运行;成功打开的话,锁会一直持有到程序退出。
import os import sys import win32file import win32api def check_single_instance(lock_file_path): try: # 创建/打开隐藏锁文件,独占访问,拒绝其他进程读写 handle = win32file.CreateFile( lock_file_path, win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0, # 不允许任何共享模式 None, win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_HIDDEN, None ) return handle except win32api.error as e: # 错误码32=文件被其他进程占用 if e.winerror == 32: return None else: raise if __name__ == "__main__": # 锁文件放在EXE同目录的共享驱动器下 lock_file = os.path.join(os.path.dirname(sys.argv[0]), ".blah_lock") instance_handle = check_single_instance(lock_file) if not instance_handle: print('Someone else is running "Blah.exe". Please be patient.') sys.exit(1) try: # -------------------------- # 这里写你的主程序逻辑 print("程序正在运行...") input("按回车键退出测试...") # -------------------------- finally: # 显式关闭句柄(可选,程序退出时系统会自动释放,但更规范) win32file.CloseHandle(instance_handle) # 删除锁文件,避免残留(不删也没关系,下次会覆盖) os.remove(lock_file)
打包时注意:如果PyInstaller没自动包含win32file和win32api,打包命令加参数:
pyinstaller --hidden-import win32file --hidden-import win32api your_script.py
方案二:用portalocker库(跨平台,代码更简洁)
如果需要跨平台兼容,或者想写更简洁的代码,可以用portalocker这个专门处理文件锁的库:
- 先安装库:
pip install portalocker
- 代码实现:
import os import sys import portalocker def check_single_instance(lock_file_path): try: lock_file = open(lock_file_path, "w") # 加独占锁,非阻塞模式 portalocker.lock(lock_file, portalocker.LOCK_EX | portalocker.LOCK_NB) return lock_file except portalocker.LockException: return None if __name__ == "__main__": lock_file = os.path.join(os.path.dirname(sys.argv[0]), ".blah_lock") instance_lock = check_single_instance(lock_file) if not instance_lock: print('Someone else is running "Blah.exe". Please be patient.') sys.exit(1) try: # -------------------------- # 主程序逻辑写在这里 print("程序正在运行...") input("按回车键退出测试...") # -------------------------- finally: portalocker.unlock(instance_lock) instance_lock.close() os.remove(lock_file)
打包时如果遇到依赖问题,同样可以加--hidden-import portalocker参数。
几个关键注意点
- 锁文件一定要放在所有用户都有读写权限的共享目录下,不然会因为权限不足创建失败。
- 别直接锁EXE文件本身——Windows运行EXE时会自动锁定它,会导致其他用户连读取EXE都出问题,用单独的隐藏锁文件更安全。
- 不管哪种方案,程序异常退出(比如Ctrl+C、崩溃)时,系统都会自动释放锁,完全不会出现残留文件导致无法启动的问题,这比你最初的方案靠谱多了。
内容的提问来源于stack exchange,提问作者rhaskett
相关产品推荐
相关产品推荐

