1.背景

如果你想用Python开发Windows程序,并让其开机启动等,就必须写成windows的服务程序Windows Service,用Python来做这个事情必须要借助第三方模块pywin32,自己去下载然后安装(注意下载符合自己OS的版本)

2.实例

先上代码

#encoding=utf-8
import win32serviceutil
import win32service
import win32event
import os
import logging
import inspect
import servicemanager class PythonService(win32serviceutil.ServiceFramework): _svc_name_ = "PythonService" #服务名
_svc_display_name_ = "Python Service Test" #服务在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 = logging.getLogger('[PythonService]') this_file = inspect.getfile(inspect.currentframe())
dirpath = os.path.abspath(os.path.dirname(this_file))
handler = logging.FileHandler(os.path.join(dirpath, "service.log")) formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter) logger.addHandler(handler)
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, details:
if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
win32serviceutil.usage()
else:
win32serviceutil.HandleCommandLine(PythonService)

解释一下代码:

1).在类PythonService的__init__函数执行完后,系统服务开始启动,windows系统会自动调用SvcDoRun函数,这个函数的执行不可以结束,因为结束就代表服务停止。所以当我们放自己的代码在SvcDoRun函数中执行的时候,必须确保该函数不退出。

2).当停止服务的时候,系统会调用SvcDoStop函数,该函数通过设置标志位等方式让SvcDoRun函数退出,就是正常的停止服务。例子中是通过event事件让SvcDoRun函数停止等待,从而退出该函数,从而使服务停止。系统关机时不会调用SvcDoStop函数,所以这种服务是可以设置为开机自启的。

3.服务操作命令

#1.安装服务

python PythonService.py install

#2.让服务自动启动

python PythonService.py --startup auto install 

#3.启动服务

python PythonService.py start

#4.重启服务

python PythonService.py restart

#5.停止服务

python PythonService.py stop

#6.删除/卸载服务

python PythonService.py remove

4.使用pyinstaller打包exe

pyinstaller.exe -F -c winService.py

效果:

5.管理windows服务操作

#!/usr/bin/env python
# -*- coding: UTF8 -*-
#
import win32service
import win32con
import time, sys
import datetime
reload(sys)
sys.setdefaultencoding("utf8")
class ServiceManager(object):
"""管理window服务""" def __init__(self, name):
"""
name: 服务的名称
"""
self.name = name #启动或停止服务时等待操作成功等待时间
self.wait_time = 0.5
#启动或停止服务时最大等待时间,超过时返回超时提示
self.delay_time = 10
self.scm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) if self.is_exists():
try:
self.handle = win32service.OpenService(self.scm, self.name, win32service.SC_MANAGER_ALL_ACCESS)
except Exception, e:
self.log(e)
else:
print '服务 %s 没有安装'.encode('gbk') % self.name def is_stop(self):
"""检查服务是否停止"""
flag = False
try:
if self.handle:
ret = win32service.QueryServiceStatus(self.handle)
flag = ret[1] != win32service.SERVICE_RUNNING
except Exception, e:
self.log(e)
return flag def start(self):
"""开启服务"""
try:
if self.handle:
win32service.StartService(self.handle, None)
except Exception, e:
self.log(e)
status_info = win32service.QueryServiceStatus(self.handle) if status_info[1] == win32service.SERVICE_RUNNING:
return '启动服务%s成功'.encode('gbk') % self.name
elif status_info[1] == win32service.SERVICE_START_PENDING:
#如果服务正在启动中则延迟返回启动信息,直到启动成功,或返回启动时间过长信息
start_time = datetime.datetime.now()
while True:
if (datetime.datetime.now() - start_time).seconds > self.delay_time:
return '启动服务%s时间太长'.encode('gbk') % self.name time.sleep(self.wait_time)
if win32service.QueryServiceStatus(self.handle)[1] == win32service.SERVICE_RUNNING:
return '启动服务%s成功'.encode('gbk') % self.name
else:
return '启动服务%s失败'.encode('gbk') % self.name def stop(self):
"""停止服务"""
try:
status_info = win32service.ControlService(self.handle, win32service.SERVICE_CONTROL_STOP)
except Exception, e:
self.log(e)
if status_info[1] == win32service.SERVICE_STOPPED:
return '停止服务%s成功'.encode('gbk') % self.name
elif status_info[1] == win32service.SERVICE_STOP_PENDING:
start_time = datetime.datetime.now()
while True:
if (datetime.datetime.now() - start_time).seconds > self.delay_time:
return '停止服务%s时间太长'.encode('gbk') % self.name time.sleep(self.wait_time)
if win32service.QueryServiceStatus(self.handle)[1] == win32service.SERVICE_STOPPED:
return '停止服务%s成功'.encode('gbk') % self.name
else:
return '停止服务%s失败'.encode('gbk') % self.name def restart(self):
"""重启服务"""
if not self.is_stop():
self.stop()
self.start()
return win32service.QueryServiceStatus(self.handle) def status(self):
"""获取运行的状态"""
try:
status_info = win32service.QueryServiceStatus(self.handle)
status = status_info[1]
if status == win32service.SERVICE_STOPPED:
return "STOPPED"
elif status == win32service.SERVICE_START_PENDING:
return "STARTING"
elif status == win32service.SERVICE_STOP_PENDING:
return "STOPPING"
elif status == win32service.SERVICE_RUNNING:
return "RUNNING"
except Exception, e:
self.log(e) def close(self):
"""释放资源"""
try:
if self.scm:
win32service.CloseServiceHandle(self.handle)
win32service.CloseServiceHandle(self.scm)
except Exception, e:
self.log(e) def is_exists(self):
"""windows服务是否已安装"""
statuses = win32service.EnumServicesStatus(self.scm, win32service.SERVICE_WIN32, win32service.SERVICE_STATE_ALL)
for (short_name, desc, status) in statuses:
if short_name == self.name:
return True
return False def log(self, exception): print(exception) if __name__=='__main__': app= ServiceManager('PythonService')
msg= app.is_exists() # 判断是否安装 (以下操作必须先判断服务是否存在)
#msg= app.is_stop() # 判断服务是否停止
#msg= app.status() # 查看服务的状态
#msg= app.start() # 开启服务
#msg= app.stop() # 暂停服务 (服务开启才能停止,else error)
#msg= app.restart() # 重启服务 print(msg)

使用Python写Windows Service服务程序的更多相关文章

  1. Python 写Windows Service服务程序

    1.需求 为什么要开发一个windows服务呢?之前做一个程序,必须要读取指定目录文件License, 因为其他程序也在读取这指定目录的License文件,且License不同时会修改License的 ...

  2. python实现windows Service服务程序

    python实现windows Service服务程序 win32serviceutil.ServiceFramework是封装得很好的Windows服务框架,本文通过继承它来实现. 通过SvcDoR ...

  3. Python3 写Windows Service服务程序

    用Python开发Windows Service,用Python来做这个事情必须要借助第三方模块pywin32,下载路径:https://pypi.org/project/pywin32/#files ...

  4. 用python写windows服务

    用python写windows服务(1) 以python2.5 为例需要软件 * python 2.5        * pywin32(与2.5 版本相匹配的) Service Control Ma ...

  5. 使用Advanced Installer 13.1打包发布 Windows Service服务程序

    原文: 使用Advanced Installer 13.1打包发布 Windows Service服务程序 项目中需要用到一个定时推送案件状态的需求,本人小菜一只,在同事建议下要写成一个windows ...

  6. C#Windows Service服务程序的安装/卸载、启动/停止 桌面客户端管理程序设计

    C#Windows Service服务程序的安装/卸载.启动/停止 桌面客户端管理程序设计 关于Windows Service程序的安装与卸载如果每次使用命令行操作,那简直要奔溃了,太麻烦而且还容易出 ...

  7. C#写Windows Service(windows服务程序)

    背景:        要学习使用一个新东西,我们必须知道他是个什么东西.对于我们此次研究的windows服务来说,他又是个什么东西,其实也没有什么高深的了. windows service概述: 一个 ...

  8. 【python】使用python写windows服务

    背景 运维windows服务器的同学都知道,windows服务器进行批量管理的时候非常麻烦,没有比较顺手的工具,虽然saltstack和ansible都能够支持windows操作,但是使用起来总感觉不 ...

  9. C#Windows Service程序的创建安装与卸载

    C#Windows Service程序的创建安装与卸载 一.开发环境 操作系统:Windows7x64 sp1 专业版 开发环境:Visual studio 2013 编程语言:C# .NET版本: ...

随机推荐

  1. RSA加密(C语言)

    /** * \file rsa.h * * \brief The RSA public-key cryptosystem * * Copyright (C) 2006-2010, Brainspark ...

  2. EXPORT_SYMBOL的使用

    转自:http://blog.csdn.net/cailiwei712/article/details/7998525 在查看内核驱动代码的时候会经常看到在一些函数后面总会跟EXPORT_SYMBOL ...

  3. SignalR 2.1 简单入门项目

    概述 SignalR是通讯框架,前台Web页面与后台服务实现数据的交互.ASP.NET SignalR 是一个为 ASP.NET 开发人员的库,简化了将实时 web 功能添加到应用程序的过程.实时We ...

  4. 【Java EE 学习 36】【struts2】【struts2系统验证】【struts2 ognl值栈】【struts2 ongl标签】【struts2 UI标签】【struts2模型驱动和令牌机制】

    一.struts2系统验证 1.基于struts2系统验证的方式实际上就是通过配置xml文件的方式达到验证的目的. 2.实际上系统校验的方法和手工校验的方法在底层的基本实现是相同的.但是使用系统校验的 ...

  5. SharePoint 2013 Apps TokenHelper SharePointContext OAuth Provider-Hosted App (抄袭,测试 csc.rsp 用)

    namespace Microshaoft.SharePointApps { using Microsoft.IdentityModel; using Microsoft.IdentityModel. ...

  6. [C++11][数据结构]自己的双链表实现

    这个双链表,是我模仿stl的list制作的,只实现了一些基本功能,像merge,transfer这些就没有实现,用户可以用基本操作来自己做外部实现. 我没有选用stl的[begin,end)迭代器模式 ...

  7. lua52 C API测试代码

    //这是一篇lua与C++交互的情景测试 #include <lua.hpp> #include <lauxlib.h> #include <lualib.h> # ...

  8. 首师大附中互测题:50136142WXY的坑爹百度地图【B006】(可以喝的超大桶水)

    [B006]50136142WXY的坑爹百度地图[难度B]——————————————————————————————————————————————————————————————————————— ...

  9. 重置按钮小tip—为何不能重置表单数据呢

    刚开始学html的同志有时候可能会遇到一个问题,就是为什么在编辑页面里面的重置按钮总是不起作用呢不清空数据呢?接下来就说明一下原因. Reset 对象 Reset 对象代表 HTML 表单中的一个重置 ...

  10. jquery取值

    1. 如何用jquery获取<input id="test" name="test" type="text"/>中输入的值?$( ...