用 Python 编写的 Windows 服务仅在调试模式下工作
Posted
技术标签:
【中文标题】用 Python 编写的 Windows 服务仅在调试模式下工作【英文标题】:Windows service written in Python works only in debug mode 【发布时间】:2015-04-11 16:57:55 【问题描述】:我编写了一个简单的 Windows 服务,它应该使用 websockets 来报告 VirtualBox 机器的状态。
安装并启动服务后,我的 websocket 服务器收到连接请求,但连接几乎立即关闭。
我启动服务时的服务器输出
running on port 8888
new connection
connection closed
使用pythonservice.exe -debug myservice
运行服务会打开一个 websocket 连接并发送我期望的数据。
我启动服务时的服务器输出带有调试标志
running on port 8888
new connection
message received VM NAME: win1, Memory: 111, CPUS: 1
message received VM NAME: win2, Memory: 266, CPUS: 1
message received VM NAME: win3, Memory: 256, CPUS: 1
message received VM NAME: lin1, Memory: 256, CPUS: 1
message received VM NAME: lin2, Memory: 200, CPUS: 1
message received VM NAME: lin3, Memory: 222, CPUS: 1
connection closed
服务来源:
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
import logging
import virtualbox
from websocket import create_connection
ws = create_connection("ws://192.168.56.1:8888/ws")
class VMInventory(win32serviceutil.ServiceFramework):
_svc_name_ = "VMInventory"
_svc_display_name_ = "VMInventory service"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.stop_event = win32event.CreateEvent(None,0,0,None)
socket.setdefaulttimeout(60)
self.stop_requested = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
self.stop_requested = True
def SvcDoRun(self):
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,'')
)
self.main()
def main(self):
# Simulate a main loop
vb = virtualbox.VirtualBox()
while True:
vms = vb.machines
if self.stop_requested:
break
for vm in vms:
ws.send("VM NAME: %s, Memory: %s, CPUS: %s" % (vm.name, str(vm.memory_size), str(vm.cpu_count)))
time.sleep(5)
ws.close()
return
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(HelloWorldSvc)
【问题讨论】:
-debug
选项所做的只是将 stdout/stderr 附加到终端,因此可能是您的服务代码尝试将输出发送到其中之一,但由于它们不存在于非-调试模式,仅在该模式下运行时尝试导致致命错误。
好吧,我的服务没有标准输出,它只创建一个 websocket 连接并将一些数据发送到远程服务器。我编辑了代码以将该数据写入文件,并且与以前一样,只有在我以调试模式运行服务时才会写入文件。
某些内容可能正在写入 stderr...例如来自未处理的异常。也许您需要使用一些扩展的 try/except
子句来加强服务的错误处理。
【参考方案1】:
服务本身运行良好,我的安装方法错误。正确的安装方式是
python aservice.py --username <username> --password <PASSWORD> --startup auto install
如果使用本地帐户,<username>
前缀为 .\
,如果使用域帐户,则前缀为 DOMAIN\
。
例如
python aservice.py --username .\johndoe --password mYstr0ngp4$$ --startup auto install
【讨论】:
【参考方案2】:您也可以只从提升的提示符处运行命令,因此右键单击“Run-As_Administrator”。除非您必须在特定用户下运行。
【讨论】:
以上是关于用 Python 编写的 Windows 服务仅在调试模式下工作的主要内容,如果未能解决你的问题,请参考以下文章
python 生成Chrome书签的html文件(仅在Windows上测试)