python编写windows服务

python编写windows服务

  • 所需库
  • 代码框架
  • windows无法及时启动或响应控制请求
  • 服务无法启动
  • 服务无法停止

所需库

import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import win32timezone
import os
import subprocess
import pickle
import shutil

代码框架

#encoding=utf-8 
import win32serviceutil 
import win32service 
import win32event 
import os 
import logging 
import inspect
import servicemanager
import sys
import win32timezone
 
class PythonService(win32serviceutil.ServiceFramework): 
 
    _svc_name_ = "PythonService"  #服务名
    _svc_display_name_ = "ServiceTest"  #服务在windows系统中显示的名称
    _svc_description_ = "This is a python service test code "  #服务的描述
 
    def __init__(self, args): 
        win32serviceutil.ServiceFramework.__init__(self, args) 
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) 
        self.logger = self._getLogger() 
        self.run = True 
         
    def _getLogger(self): 
        # 创建一个logger,设置日志名称,为我们的模块名
        # 返回一个logger实例,如果没有指定name,返回root logger。
        # 只要name相同,返回的logger实例都是同一个而且只有一个,
        # 即name和logger实例是一一对应的。这意味着,
        # 无需把logger实例在各个模块中传递。只要知道name,
        # 就能得到同一个logger实例。
        logger = logging.getLogger('[PythonService]') 
        # 获取当前文件夹路径 
        this_file = inspect.getfile(inspect.currentframe()) 
        dirpath = os.path.abspath(os.path.dirname(this_file))
        # 创建一个handler,用于写入日志文件
        # StreamHandler: 输出到控制台
        # FileHandler:   输出到文件
        # BaseRotatingHandler 可以按时间写入到不同的日志中。比如将日志按天写入不同   的日期结尾的文件文件。
        # SocketHandler 用TCP网络连接写LOG
        # DatagramHandler 用UDP网络连接写LOG
        # SMTPHandler 把LOG写成EMAIL邮寄出去 
        handler = logging.FileHandler(os.path.join(dirpath, "service.log")) 
        # 定义handler的输出格式
        formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s') 
        handler.setFormatter(formatter) 
         # 给logger添加handler
        logger.addHandler(handler) 
        
        # 日志等级(从高到低)CRITICAL->ERROR->WARNING->INFO->DEBUG
        # 一旦设置了日志等级,则调用比等级低的日志记录函数则不会输出
        logger.setLevel(logging.INFO) 
         
        return logger 
 
    def SvcDoRun(self): 
        import time 
        self.logger.info("service is run....")   # 记录一条日志
        while self.run: 
            self.logger.info("I am runing....") 
            time.sleep(2) 
             
    def SvcStop(self): 
        self.logger.info("service is stop....") 
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
        win32event.SetEvent(self.hWaitStop) 
        self.run = False 
 
if __name__=='__main__': 
    if len(sys.argv) == 1:
        try:
            evtsrc_dll = os.path.abspath(servicemanager.__file__)
            servicemanager.PrepareToHostSingle(PythonService)
            servicemanager.Initialize('PythonService', evtsrc_dll)
            servicemanager.StartServiceCtrlDispatcher()
        except win32service.error as details:
            if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
                win32serviceutil.usage()
    else:
        win32serviceutil.HandleCommandLine(PythonService)

windows无法及时启动或响应控制请求

解决方案:将Python36\Lib\site-packages\win32路径下的pythonservice.exe注册一下。

               注册命令:pythonservice.exe /register

如果缺少pywintypes37.dll
该文件在Python36\Lib\site-packages\pywin32_system32路径。

解决方法:设置到环境变量或者将此dll copy到Python36\Lib\site-packages\win32。

服务无法启动

可能原因:
1.服务中存在bug,导致无法启动,需修改bug
2.服务中存在权限问题
3.其中可能存在打开文件路径错误,配置文件要写绝对路径

服务无法停止

可手动在进程序列中找到pythonserve.exe,将其停止

你可能感兴趣的:(python编写windows服务)