2015-04-22 40 views
-1

我正在編寫一個腳本,它將在計算機上持續運行。由於它必須在沒有安裝python的計算機上運行,​​因此我計劃將其轉換爲可執行文件。我也想有一個GUI來啓動和停止這個應用程序,但我不想讓這個GUI始終打開。我的意思是如果GUI被關閉,我不希望可執行文件停止運行。只有在用戶按下GUI上的停止按鈕時才應該停止。這個GUI只是用戶啓動和停止可執行文件的界面。Python:用於連續運行腳本的GUI

我該如何實現這種行爲?

+0

檢查例如http://cyrille.rossant.net/create-a-standalone-windows-installer-for-your-python-application/ – Jaco

+1

你能提供你已經嘗試過什麼,所以一些信息遠? – Totem

+0

@Totem:kivy如何幫助這個? – abarnert

回答

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等。

+0

謝謝@abrnert。 – rahulchem

0

Thanks @ 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() 
+0

我不明白爲什麼你在停止它後60秒後殺死後臺進程。另外,爲了編寫單個字符串,你需要'f.write',而不是'f.writelines'。 ('f.writelines'會假定你的字符串是一個序列,將其分解成1個字符的序列,並假設每個序列已經有一個換行符,所以它不會添加一個,所以最終得到的輸出相同,但是速度較慢,並且如果有人在中間插入插件,則更可能會損壞。)最後,您可能需要使用'os.path.dirname(os.path.abspath(sys.argv [1]))'而不是當前工作目錄。 – abarnert

+0

另外,'with'語句比顯式的'close'好 - 除了保存一行代碼,這意味着如果'read'產生一個異常,文件仍然會被關閉。你不應該需要'win32api'; 'os.kill'應該可以正常工作。 (請參閱文檔;除特殊的^ C/Break值之外的任何內容都會爲您調用TerminateProcess。)但除了那些小小的細節之外,這一切看起來都不錯。 – abarnert