#python
#python
Вопрос:
Если у меня есть исполняемый файл python, скомпилированный в exe, как я могу проверить, запущен ли он уже в диспетчере задач, и если да, не запускать его новый экземпляр?
import wmi
if (c.Win32_Process(name="Script.exe")):
sys.exit()
else:
#script.exe's code
Приведенный выше код использует модуль wmi, чтобы проверить, запущена ли программа, а затем остановить запуск нового экземпляра. Проблема в том, что скрипт никогда не будет запущен. Это связано с тем, что при script.exe если он запускается в первый раз, он сразу же появляется в диспетчере задач. Модуль WMI обнаруживает это и закрывает его, как только он открывается. Я подтвердил это, переименовав исполняемый файл в Script2.exe , который запускает программу просто отлично.
Есть ли какой-либо способ правильно проверить, запущен ли исполняемый файл python?
Ответ №1:
Если файл не удаляется при завершении работы системы, вы можете попробовать это:
Создайте папку temp .txt в любом месте вашей системы, затем запретите доступ к ней любым другим программам, заставив python думать, что она «в настоящее время используется другой программой». Например:
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()
Если будет запущен другой экземпляр программы, вы получите PermissionError и программа закроется.
Комментарии:
1. Аккуратное решение. Просто обратите внимание, что это работает только в Windows. И даже тогда он может также сломаться при странных обстоятельствах, например, если файл блокировки хранится в общей сетевой папке, как бы маловероятно это ни было.
Ответ №2:
Одним из общих методов для этого является блокировка файлов. Иногда также называемые файлами pid.
Когда процесс запускается, он создает файл в предопределенном месте. Если процесс запускается и файл существует, вы предполагаете, что процесс уже запущен. После завершения процесса он должен очистить свой файл блокировки.
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
Можно было бы улучшить обработку, но это основная идея.
Вы также можете написать свою программу для запуска в качестве службы Windows (демона).
Не идеально, но вы также можете улучшить свое решение, проверив текущее pid
значение и название программы.
for process in processes:
if process.pid != os.getpid() and process.name == script_name:
sys.exit(1)
Одна из причин, по которой это не идеально, заключается в том, что имя исполняемого файла не гарантируется (как вы отметили, имя файла может быть просто изменено, и это прерывается)
Комментарии:
1. Это решение идеально подходит для большинства скриптов на Python. Однако мой скрипт должен постоянно выполняться в фоновом режиме. Поскольку у процесса нет реального «конца», когда файл блокировки удаляется, процесс продолжается. Это позволяет вызывать его снова, пока предыдущая версия все еще запущена.
2. Это решение все еще работает в этом случае.
when the lock file is removed
Файл блокировки не будет удален сам по себе. Единственный случай, когда его следует удалить, — это когда программа останавливается. Если программа никогда не останавливается (main()
выполняется вечно), файл никогда не будет удален.finally:
Предложение предназначено для ситуаций, например, если система завершает работу. Python попытается очистить файл перед выключением системы, поэтому процесс может начаться при запуске процесса после восстановления системы.3. На самом деле я не продумал все до конца — это действительно работает!
4. Рад, что это работает для вас. Я также добавил пару альтернатив, а также пищу для размышлений 🙂
Ответ №3:
is_process_exists
возвращает True
, если процесс существует, False
если нет:
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])
Комментарии:
1. Я думаю, что проблема в этом случае заключается в том, что сам скрипт пытается проверить, запущен ли процесс… но, конечно, он всегда будет запущен, если программа проверяет свое собственное имя 🙂