將一個Python指令碼做成一個Windows服務

韩、饭饭發表於2024-12-10

問題描述:假設我們有一個Python指令碼,這個指令碼是一個後臺任務,需要在Windows系統中長時間執行。為了方便管理和監控,我們希望將這個指令碼封裝成一個Windows服務。這樣,我們可以使用服務管理器來啟動、停止、重啟和監控這個指令碼。

解決方案
第一步:安裝pywin32模組

在命令列中執行以下命令來安裝pywin32模組:pip install pywin32

第二步:建立服務指令碼

在Python指令碼中,我們需要引入win32service和win32serviceutil模組來建立和管理服務。

以下是一個簡單的示例指令碼,它可以作為一個Windows服務執行並定期輸出一條日誌資訊:

## 程式碼塊1
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import os
import sys
import logging
import inspect
import time

# 服務名稱
svc_name = 'MyService'

# 服務顯示名稱
svc_display_name = 'My Service'

# 服務描述
svc_description = 'This is a sample service.'

# 服務日誌檔案路徑
svc_log_file = r'C:\path\to\log_file.txt'

# 日誌格式
log_format = '[%(asctime)s] %(levelname)s: %(message)s'
logging.basicConfig(filename=svc_log_file, level=logging.INFO, format=log_format)

class MyService(win32serviceutil.ServiceFramework):
    _svc_name_ = svc_name
    _svc_display_name_ = svc_display_name
    _svc_description_ = svc_description

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        socket.setdefaulttimeout(60)
        self.is_running = True

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.is_running = False

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_, ''))
        self.main()

    def main(self):
        while self.is_running:
            logging.info('Service is running...')
            # 在這裡編寫你的任務程式碼
            time.sleep(5)在這個示例中,我們定義了一個名為MyService的類,繼承自win32serviceutil.ServiceFramework。我們需要在這個類中實現SvcDoRun方法來定義服務的主邏輯。在本例中,我們簡單地輸出一條日誌資訊,並透過time.sleep(5)來模擬一個長時間執行的任務。

if __name__ == '__main__':
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(MyService)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(MyService)

在這個示例中,我們定義了一個名為MyService的類,繼承自win32serviceutil.ServiceFramework。我們需要在這個類中實現SvcDoRun方法來定義服務的主邏輯。在本例中,我們簡單地輸出一條日誌資訊,並透過time.sleep(5)來模擬一個長時間執行的任務。

第三步:安裝服務

開啟命令提示符視窗,切換到指令碼所在的目錄。

執行以下命令來安裝服務:python xx.py install

這將會建立一個Windows服務並註冊到服務管理器中。

第四步:啟動服務

執行以下命令來啟動服務:python xx.py start

第五步:管理服務

可以使用以下命令來管理服務:

停止服務:python script.py stop
重啟服務:python script.py restart
刪除服務:python script.py remove

序列圖:

sequenceDiagram
participant User
participant Service
User->>Service: 啟動服務
Service->>User: 服務已啟動
User->>Service: 停止服務
Service->>User: 服務已停止
User->>Service: 重啟服務
Service->>User: 服務已重啟
User->>Service:


如下圖,建立的服務My Service如下:

-----------------------------------
©著作權歸作者所有:來自51CTO部落格作者mob64ca12f5c08e的原創作品,請聯絡作者獲取轉載授權,否則將追究法律責任
如何把一個python 指令碼做成一個windows 服務
https://blog.51cto.com/u_16213454/9371117

相關文章