Python制作Windows系统服务Python制作Windows系统服务

Python制作Windows系统服务

最近有个Python程序需要安装并作为Windows系统服务来运行,过程中碰到一些坑,整理了一下。

安装 

pip install pyinstaller pywin32

Python服务类

首先Python程序需要调用一些Windows系统API才能作为系统服务,具体内容如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import time

import win32api
import win32event
import win32service
import win32serviceutil
import servicemanager
import win32timezone

import os
import logging
import re
from logging.handlers import TimedRotatingFileHandler
from datetime import datetime
from threading import Timer

import requests
import json

def setup_log(log_name):
    # 创建logger对象。传入logger名字
    logger = logging.getLogger(log_name)
    log_path = os.path.join("D:\\tongbudaozhashijian\\",log_name)
    # 设置日志记录等级
    logger.setLevel(logging.INFO)
    # interval 滚动周期,
    # when="MIDNIGHT", interval=1 表示每天0点为更新点,每天生成一个文件
    # backupCount  表示日志保存个数
    # 通过设置TimedRotatingFileHandler进行日志按周(W)、天(D)、时(H)、分(M)、秒(S)切割。
    file_handler = TimedRotatingFileHandler(
        filename=log_path, when="MIDNIGHT", interval=1, backupCount=30
    )
    # filename="mylog" suffix设置,会生成文件名为mylog.2020-02-25.log
    file_handler.suffix = "%Y-%m-%d.log"
    # extMatch是编译好正则表达式,用于匹配日志文件名后缀
    # 需要注意的是suffix和extMatch一定要匹配的上,如果不匹配,过期日志不会被删除。
    file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}:.log$")
    # 定义日志输出格式
    file_handler.setFormatter(
        logging.Formatter(
            "[%(asctime)s] [%(process)d] [%(levelname)s] - %(module)s.%(funcName)s (%(filename)s:%(lineno)d) - %(message)s"
        )
    )
    logger.addHandler(file_handler)
    return logger



def task():
    try:

        logger = logging.getLogger("mylog")
        # logger.debug('debug 信息')
        # logger.info('info 信息')
        # logger.warning('warning 信息')
        # logger.error('error 信息')
        # logger.critical('critial 信息')


        now = datetime.now()
        ts = now.strftime("%Y-%m-%d %H:%M:%S")
        url = "http://192.168.0.69/Home/SetSynchronizeTime"
        data = {"key": "EBBD366937FCAD4AF67D7D018DFEF8A8", "channelout": "2", "time": ts}
        logger.info(data)
        ## headers中添加上content-type这个参数,指定为json格式
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        res = requests.post(url=url, headers=headers, data=json.dumps(data), timeout=3)
        logger.info(res.text)
    except Exception as e:
        logger.error(e)




def func():
    task()
    t = Timer(60*10, func)
    t.start()

class MyService(win32serviceutil.ServiceFramework):

    _svc_name_ = "tongbudaozhashijian"
    _svc_display_name_ = "同步道闸时间"
    _svc_description_ = "同步道闸时间"
    logger = logging.getLogger("mylog")

    def __init__(self, args):
        logger.info('init')
        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.ReportServiceStatus(win32service.SERVICE_RUNNING)
            logger.info('start')
            self.start()
            logger.info('wait')
            win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
            logger.info('done')
        except BaseException as e:
            logger.error('Exception : %s' % e)
            self.SvcStop()

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        logger.info('stopping')
        self.stop()
        logger.info('stopped')
        win32event.SetEvent(self.stop_event)
        self.ReportServiceStatus(win32service.SERVICE_STOPPED)

    def start(self):
        func()

    def stop(self):
        pass

    def log(self, msg):
        servicemanager.LogInfoMsg(str(msg))

    def sleep(self, minute):
        win32api.Sleep((minute*1000), True)

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

pyinstaller打包

pyinstaller -F MyService.py

测试

# 安装服务
dist\MyService.exe install

# 启动服务
sc start MyService

# 停止服务
sc stop MyService

# 删除服务
sc delete MyService

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值