如何让程序在启动时关闭当前 运行 实例?
How to make a program close it's currently running instance upon startup?
我有一个命令行程序,我想保留它 运行 直到我再次打开它,所以基本上是一个程序,它首先检查当前是否已经存在 运行 自身的实例,并且杀了它。
我试过os.system('TASKKILL /F /IM program.exe')
但结果很愚蠢,因为它也会自杀。
您可以使用已经 运行 个实例的进程 ID。
import os
os.system("taskkill /pid <ProcessID>")
确保您的应用程序只有一个实例的最可靠方法是在已知(固定)位置创建一个 pid 文件。此位置通常位于您的应用程序数据文件夹或临时目录中。在启动时,您应该检查 pid 文件是否存在以及其中包含的 pid 是否仍然存在并引用您的目标进程。如果它存在,向它发送一个 kill 信号,然后在启动应用程序的其余部分之前用您当前的 pid 覆盖该文件。
为了更加安全,您可能需要等到之前的进程完全终止。这可以通过 waiting/polling 来检查具有该 pid 的进程是否仍然存在,或者通过轮询被杀死的进程以删除其自己的 pid 文件来完成。如果进程关闭时间非常长并且您希望在旧进程关闭时允许当前进程已经开始工作,则后者可能是必要的。
您可以使用 psutil
库。它只是遍历所有 运行ning 进程,过滤具有特定文件名的进程,如果它们的 PID 与当前进程不同,则杀死它们。它也将 运行 在任何平台上,考虑到你有一个正确的进程文件名。
import psutil
process_to_kill = "program.exe"
# get PID of the current process
my_pid = os.getpid()
# iterate through all running processes
for p in psutil.process_iter():
# if it's process we're looking for...
if p.name() == process_to_kill:
# and if the process has a different PID than the current process, kill it
if not p.pid == my_pid:
p.terminate()
如果只是程序文件名不够唯一,您可以使用方法Process.exe()
代替,它返回过程映像的完整路径:
process_to_kill = "c:\some\path\program.exe"
for p in psutil.process_iter():
if p.exe() == process_to_kill:
# ...
因为我的工作站无法访问互联网并且安装软件包很麻烦,所以我最终想出了这个解决方案:
import os
os.system('tasklist > location/tasks.txt')
with open('location/tasks.txt', 'r') as pslist:
for line in pslist:
if line.startswith('python.exe'):
if line.split()[1] != str(os.getpid()):
os.system(f'TASKKILL /F /PID {line.split()[1]}')
break
os.remove('location/tasks.txt')
它将 tasklist 命令的输出打印到一个文件中,然后检查该文件以查看是否有运行 python 进程的 PID 与其自身不同。
编辑:发现我可以用 popen
做到这一点,所以它更短并且不涉及文件:
import os
for line in os.popen('tasklist').readlines():
if line.startswith('python.exe'):
if line.split()[1] != str(os.getpid()):
os.system(f'taskkill /F /PID {line.split()[1]}')
break
我有一个命令行程序,我想保留它 运行 直到我再次打开它,所以基本上是一个程序,它首先检查当前是否已经存在 运行 自身的实例,并且杀了它。
我试过os.system('TASKKILL /F /IM program.exe')
但结果很愚蠢,因为它也会自杀。
您可以使用已经 运行 个实例的进程 ID。
import os
os.system("taskkill /pid <ProcessID>")
确保您的应用程序只有一个实例的最可靠方法是在已知(固定)位置创建一个 pid 文件。此位置通常位于您的应用程序数据文件夹或临时目录中。在启动时,您应该检查 pid 文件是否存在以及其中包含的 pid 是否仍然存在并引用您的目标进程。如果它存在,向它发送一个 kill 信号,然后在启动应用程序的其余部分之前用您当前的 pid 覆盖该文件。
为了更加安全,您可能需要等到之前的进程完全终止。这可以通过 waiting/polling 来检查具有该 pid 的进程是否仍然存在,或者通过轮询被杀死的进程以删除其自己的 pid 文件来完成。如果进程关闭时间非常长并且您希望在旧进程关闭时允许当前进程已经开始工作,则后者可能是必要的。
您可以使用 psutil
库。它只是遍历所有 运行ning 进程,过滤具有特定文件名的进程,如果它们的 PID 与当前进程不同,则杀死它们。它也将 运行 在任何平台上,考虑到你有一个正确的进程文件名。
import psutil
process_to_kill = "program.exe"
# get PID of the current process
my_pid = os.getpid()
# iterate through all running processes
for p in psutil.process_iter():
# if it's process we're looking for...
if p.name() == process_to_kill:
# and if the process has a different PID than the current process, kill it
if not p.pid == my_pid:
p.terminate()
如果只是程序文件名不够唯一,您可以使用方法Process.exe()
代替,它返回过程映像的完整路径:
process_to_kill = "c:\some\path\program.exe"
for p in psutil.process_iter():
if p.exe() == process_to_kill:
# ...
因为我的工作站无法访问互联网并且安装软件包很麻烦,所以我最终想出了这个解决方案:
import os
os.system('tasklist > location/tasks.txt')
with open('location/tasks.txt', 'r') as pslist:
for line in pslist:
if line.startswith('python.exe'):
if line.split()[1] != str(os.getpid()):
os.system(f'TASKKILL /F /PID {line.split()[1]}')
break
os.remove('location/tasks.txt')
它将 tasklist 命令的输出打印到一个文件中,然后检查该文件以查看是否有运行 python 进程的 PID 与其自身不同。
编辑:发现我可以用 popen
做到这一点,所以它更短并且不涉及文件:
import os
for line in os.popen('tasklist').readlines():
if line.startswith('python.exe'):
if line.split()[1] != str(os.getpid()):
os.system(f'taskkill /F /PID {line.split()[1]}')
break