2017-03-04 129 views
0

我第一次在this post中發佈了答案,但它不符合論壇標準。我希望這次的答案符合論壇標準。此代碼應該更清晰易讀。Python 3 Windows Service僅在調試模式下啓動

在Python 3+我有用來構建一個Windows服務下面的類(什麼都不做,只是寫入日誌文件):

#MyWindowsService.py 
import win32serviceutil 
import servicemanager 
import win32service 
import win32event 
import sys 
import logging 
import win32api 


class MyWindowsService(win32serviceutil.ServiceFramework): 
    _svc_name_   = 'ServiceName' 
    _svc_display_name_ = 'Service Display Name' 
    _svc_description_ = 'Service Full Description' 
    logging.basicConfig(
     filename = 'c:\\Temp\\{}.log'.format(_svc_name_), 
     level  = logging.DEBUG, 
     format  = '%(levelname)-7.7s @ %(asctime)s: %(message)s' 
    ) 

    def __init__(self, *args): 
     self.log('Initializing service {}'.format(self._svc_name_)) 
     win32serviceutil.ServiceFramework.__init__(self, *args) 
     self.stop_event = win32event.CreateEvent(None, 0, 0, None) 

    def SvcDoRun(self): 
     self.ReportServiceStatus(win32service.SERVICE_START_PENDING) 
     try: 
      self.log('START: Service start') 
      self.ReportServiceStatus(win32service.SERVICE_RUNNING) 
      self.start() 
      win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE) 
     except Exception as e: 
      self.log('Exception: {}'.format(e)) 
      self.SvcStop() 

    def SvcStop(self): 
     self.log('STOP: Service stopping...') 
     self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
     self.stop() 
     win32event.SetEvent(self.stop_event) 
     self.ReportServiceStatus(win32service.SERVICE_STOPPED) 

    def log(self, msg): 
     servicemanager.LogInfoMsg(str(msg)) #system log 
     logging.info(str(msg))    #text log 

    def start(self): 
     self.runflag = True 
     while self.runflag: 
      win32api.Sleep((2*1000), True) 
      self.log('Service alive') 
    def stop(self): 
     self.runflag = False 
     self.log('Stop received') 




if __name__ == '__main__': 
    win32serviceutil.HandleCommandLine(MyWindowsService) 

在我使用日誌文件檢查腳本如果它工作正常。我在Windows 7上運行python3.6(也嘗試使用python3.4),並且遇到以下問題。當我運行python MyWindowsService.py install時,提示說服務已安裝(但沒有任何內容寫入日誌文件)。如果我嘗試啓動該服務,則會收到服務錯誤:1 - 更多信息NET HELPMSG 3547,對此錯誤沒有太多說明。如果我運行python MyWindowsService.py debug,程序運行得很好(寫入日誌文件),但仍然無法控制服務:如果我打開另一個提示並嘗試停止/啓動服務,我仍然得到相同的結果如上所述。

我也嘗試在init函數中插入一些調試代碼,當我運行python MyWindowsService.py安裝它似乎沒有被調用。可能嗎?

我已經檢查了多個解決方案和圍繞網絡的解決方法,但我沒有找到任何合適的東西。我錯過了什麼?

+0

嘗試使用'sc start ServiceName'開始服務。這可能提供更多信息。另外,使用命令「sc qc ServiceName」查詢配置。這應該顯示「PythonService.exe」的完整路徑。檢查是否可以在命令提示符下運行它。如果沒有,請確保「python36.dll」,「vcruntime140。dll「和」pywintypes36.dll「或者符號鏈接到具有PythonService.exe的目錄;或者符號鏈接到System32目錄;或者具有這些DLL的目錄在系統中(而不是用戶)」路徑「 – eryksun

+0

您好eryksun,感謝您的關注 – jekbau

+0

我檢查了您提到的dll,並將其目錄添加到了系統路徑中 - 沒有任何更改 sc start ServiceName'返回STATUS 2 START_PENDING(NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)' 我還在系統路徑中添加了「PythonService.exe」路徑 - 以防萬一,但是沒有發生任何事情 – jekbau

回答

0

正如eriksun在第一篇文章的評論中指出的那樣,問題出自python腳本的位置,這是在映射有UNC路徑的驅動器中 - 我正在使用虛擬機。將python腳本移到與python安裝相同的驅動器中,完成了這項工作。 概括起來以備將來使用,如果服務無法啓動,你可以肯定你的代碼,這些都是有益的行動,試圖解決您的問題:

  • 使用sc start ServiceNamesc query ServiceNamesc stop ServiceName得到有關該服務的信息。
  • 檢查您的文件是在物理驅動器還是在UNC映射的驅動器中。如果後者嘗試使用UNC路徑運行腳本(例如python \\Server\share\python\your-folder\script.py)或將腳本與Python安裝
  • 相同的驅動器中移動,請確保「python36.dll」,「vcruntime140.dll」和「pywintypes36 .dll「要麼符號鏈接到具有PythonService.exe的目錄;或符號鏈接到System32目錄;或與這些DLL的目錄是在系統中(而非用戶)路徑
  • 檢查系統命令reg query HKLM\System\CurrentControlSet\Services\your_service_name /s註冊以獲取有關腳本的詳細信息

請隨時來完成,變更,修改最後這樣對於像我這樣的人遇到這個問題可以是有用的。

編輯:還有一件事......我的項目被認爲實際上與網絡文件夾(和UNC映射的驅動器)工作,並且它失敗時,我試圖使其作爲服務運行。我用來使其工作的一個非常有用(節省時間)的資源是我在this post中找到的SysinternalsSuite by Mark Russinovich。希望這可以幫助。

相關問題