我正在创建一个必须一次运行一个的应用程序,因此我尝试根据以下配方创建它: https://code.activestate.com/recipes/474070-creating-a-single-instance-application/
问题是,我需要应用程序等待另一个应用程序完成然后运行。
我尝试过这样的事情:
def __init__(self) -> None:
while True:
lastError = 0
SetLastError(0)
self.Mutex = CreateMutex(None, False, self.MUTEX_NAME)
lastError = GetLastError()
if (lastError != ERROR_ALREADY_EXISTS):
break
else:
print("It's already running... Waiting...")
time.sleep(5)
def __del__(self) -> None:
if self.Mutex:
CloseHandle(self.Mutex)
当我在 VSCode 上以“调试模式”逐行运行此代码时,它可以工作,因为 GetLastError 在第一个进程完成后返回 0。
但是当我像
python app.py
那样运行两次时,第二个进程总是打印“它已经在运行......等待......”
我该如何解决?
这是预期的行为,因为第一个实例的退出不会自动清除应用程序的后续实例中的最后一个错误代码!
为了使其发挥作用,请考虑使用
WaitForSingleObject
:
import time
from ctypes import windll, byref, c_ulong
from win32event import WaitForSingleObject, WAIT_OBJECT_0, INFINITE
from win32api import GetLastError, SetLastError
from win32con import ERROR_ALREADY_EXISTS
from win32mutex import CreateMutex
class SingleInstanceApplication:
def __init__(self, mutex_name):
self.MUTEX_NAME = mutex_name
self.Mutex = None
self.ensure_single_instance()
def ensure_single_instance(self):
while True:
SetLastError(0)
self.Mutex = CreateMutex(None, False, self.MUTEX_NAME)
lastError = GetLastError()
if lastError == ERROR_ALREADY_EXISTS:
print("It's already running... Waiting...")
# Wait for the mutex to be released
wait_result = WaitForSingleObject(self.Mutex, INFINITE)
if wait_result == WAIT_OBJECT_0:
# Mutex is released, can proceed
print("Previous instance finished, starting now...")
break
else:
break # No error, mutex created successfully, proceed
def __del__(self):
if self.Mutex:
windll.kernel32.CloseHandle(self.Mutex)
if __name__ == "__main__":
app = SingleInstanceApplication("Global\\MySingleInstanceAppMutex")
# Put Your application logic here
print("Application running. Press Ctrl+C to exit.")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Application exiting.")