自学内容网 自学内容网

【Python】基于python实现Windows Service程序

0 前言

  最近揽了一个小活,就是基于Python设计一个Windows Service程序,和一般应用不同的是,Service直接运行在后台,不会在运行时弹出黑框,因此在设计上和一般的程序有些微差别。因为之前从来没有做过这个,因此做个记录。

1 代码框架

  使用Python写Windows Service,其代码的基本框架是固定的,这也大大方便降低了入门的难度。经过查找资料,加上自己的尝试,总结出如下代码基本结构。

import servicemanager
import sys
import win32event
import win32service
import win32serviceutil

class TestService(win32serviceutil.ServiceFramework):
    '''这里是一些服务的基本信息, 根据自己需要进行修改
    '''
    _svc_name_ = "TestService"
    _svc_display_name_ = "Test Service"
    _svc_description_ = "My service description"

    def __init__(self, args):
        '''初始化函数, 服务启动时调用, 可以用来初始化一些变量
        '''
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

    def SvcStop(self):
        '''停止函数, 服务停止时调用, 可以用来释放资源等操作
        '''
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        '''运行函数, 服务启动时调用, 可以在这里写你的代码, 注意要是一个死循环
        '''
        rc = None
        while rc != win32event.WAIT_OBJECT_0:
            ###########################################
            # 这里写你的代码
            ###########################################
            with open('C:\\TestService.log', 'a') as f:
                f.write('test service running...\n')
            rc = win32event.WaitForSingleObject(self.hWaitStop, 5000)

    def other_function(self):
        '''其他函数, 可以用于写其他的代码,然后在主线程中调用
        '''
        pass

if __name__ == '__main__':
    '''服务入口函数, 不用修改
    '''
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(TestService)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(TestService)

2 使用方式

  基于上述代码结构,接下来就可以根据自己需要实现的功能写代码了,和其他的开发方式没什么区别,也可以使用多线程。开发完成之后,接下来就是打包程序生成服务了,这里使用到的还是使用最为普遍的pyinstaller模块,打包指令如下

pyinstaller -F --hidden-import=win32timezone .\<文件名>.py

这样就能得到一个执行程序,接下来还需要基于这个执行程序安装,运行,暂停,卸载服务等操作,基本指令如下所示。

# 安装服务
.\dist\<执行文件名>.exe install

# 启动服务
.\dist\<执行文件名>.exe start

# 停止服务
.\dist\<执行文件名>.exe stop

# 卸载服务
.\dist\<执行文件名>.exe remove

到此,基本走完了开发流程,剩下的主要就是功能调试了,比较繁琐,不再赘述。

3 遇到的问题和解决方案

  • 卸载再安装服务显示“指定的服务已标记为删除”
      这是因为在调试过程中打开了服务那个窗口导致的,所以最简单的办法就是强制删除服务之后,重启终端,然后不再在调试过程中打开服务那个窗口,如果还不行,就重启电脑试试。

    实际上我的问题出在代码上面,因为我代码中服务执行部分有socket的accept函数,导致程序是堵塞执行的,所以实际上需要一定的时间这个服务也会自动删除。

  • Updating…


原文地址:https://blog.csdn.net/ZHOU_YONG915/article/details/137787139

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!