我正在编写一个可以在计算机上连续运行的脚本。由于它必须在没有安装python的计算机上运行,我计划将其转换为可执行文件。我也希望有一个GUI来启动和停止这个应用程序,但我不希望这个GUI一直打开。我的意思是如果GUI关闭,我不希望可执行文件停止运行。只有当用户按下GUI上的停止按钮时,它才会停止。此GUI只是用户启动和停止可执行文件的界面。
我该如何实现这种行为?
答案 0 :(得分:0)
显而易见的解决方案是拥有两个独立的程序:一个背景/守护程序/代理/服务,它只是在背景中与用户输入和输出分离,以及一个GUI程序来控制它。这个设计的一个很好的优点是你可以有一个命令行程序来控制它,如果你想远程ssh,或者从脚本控制它。
传统的Unix处理方法是使用设计为系统服务的daemon(即使它像普通用户一样运行):它在启动时将其pid写入文件,并且控制程序读取该文件并向它发现杀死它的pid发送信号。
因此,控制程序具有以下功能:
def is_running():
try:
with open(PID_PATH) as f:
pid = int(f.read())
os.kill(pid, 0)
except Exception:
return False
else:
return True
def stop():
with open(PID_PATH) as f:
pid = int(f.read())
os.kill(pid, signal.SIGUSR1)
def start():
subprocess.check_call(DAEMON_PATH)
当然,在现实生活中,您需要更好的错误处理。此外,您使用哪个信号取决于您是否希望守护程序立即死亡,或者优雅地关闭。等等。
另一种方法是让后台进程监听套接字 - 无论是具有已知端口的TCP,还是具有已知文件名的Unix套接字 - 并以这种方式与之通信。这可以让你做一些刚开始和停止的更好的事情。
在Windows上,细节并不完全相同,但你可以做类似的事情。
最后,Windows,OS X和各种Linux发行版也都有特定于平台的方式将这类内容包装在更高级别,因此您可能希望构建Windows服务,LaunchAgent等。
答案 1 :(得分:0)
谢谢@ abarnert.I使用了您的方法并转换了Windows代码。请参阅下面我的解决方案。它启动并停止helloworld.exe。我已经删除了错误处理以保持简单。
import subprocess
import time
def startprocess():
#start helloworld.exe
process = subprocess.Popen(['helloworld.exe'])
#Write down the prog id into a file for later use
f = open('progid.txt','w')
f.writelines(str(int(process._handle)))
f.close()
def endprocess():
f = open('progid.txt','r')
progid = int(f.read())
f.close()
# Kill the process using pywin32
import win32api
win32api.TerminateProcess(progid, -1)
startprocess()
time.sleep(60) #wait for 60 second before kill
endprocess()