Reputation: 146
If I have a python executable compiled to exe, how can I check if it's already running in task manager and if so, avoid running a new instance of it?
import wmi
if (c.Win32_Process(name="Script.exe")):
sys.exit()
else:
#script.exe's code
The code above uses the wmi module to check if the program is already running, then stop the new instance from running. The problem with it is that the script will never run. This is due to the fact that when script.exe is ran for the first time, it shows up immediately in task manager. The WMI module detects this and closes it as soon as it opens. I confirmed this by renaming the executable to Script2.exe, which runs the program just fine.
Is there any way to properly check if a python exe is already running?
Upvotes: 1
Views: 593
Reputation: 36
If the file doesn't remove itself when the system shuts down, you can try this:
Create a temp .txt folder anywhere on your system, then prevent any other programs from accessing it by making python think that's "currently in use by another program". For example:
import threading
import os
pth = os.getcwd() + '\\text.txt'
if os.path.exists(pth):
try:
os.remove(pth)
except PermissionError:
sys.exit()
else:
open(pth,"w+").close()
f = open(pth,"w+")
def loop():
while True:
pass
threading.Thread(target=loop).start()
If another instance of the program is ran, you will get a PermissionError and the program will close.
Upvotes: 2
Reputation: 41081
One general method for this is lock files. Sometimes also called pid files.
When the process starts, it creates a file in a predefined location. If the process starts and the file exists, you assume the process is already running. Once the process exits, it should clean up its lock file.
import os
LOCK_FILE = "C:\\Path\\To\\myapplication.lock"
if os.path.exists(LOCK_FILE):
print(f"LOCK FILE {LOCK_FILE} already exits. Exiting")
sys.exit(1)
else:
with open(LOCK_FILE, 'w') as f:
f.write(f'{os.getpid()}')
try:
main()
finally:
try:
os.remove(LOCK_FILE)
except OSError:
pass
There's some better handling that could be done, but this is the basic idea.
You could also write your program to run as a Windows service (a daemon).
Not ideal, but you could also improve upon your solution by checking the current pid
AND the program name.
for process in processes:
if process.pid != os.getpid() and process.name == script_name:
sys.exit(1)
Part of the reason this is not ideal is because the executable name is not guaranteed (as you noted, the filename can simply be changed and this breaks)
Upvotes: 2
Reputation: 8270
is_process_exists
returns True
if process exists, False
if not:
import psutil
def is_process_exists(process_name):
return bool([p for p in psutil.process_iter() if psutil.Process(p.pid).name() == process_name])
Upvotes: 0