Windows 在 Python 中编写的服务仅在调试模式下有效
Windows service written in Python works only in debug mode
我写了一个简单的 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)
服务本身没有问题,我的安装方法不对。正确的安装方式是
python aservice.py --username <username> --password <PASSWORD> --startup auto install
其中 <username>
如果使用本地帐户,则前缀为 .\
,如果使用域帐户,则前缀为 DOMAIN\
。
例如
python aservice.py --username .\johndoe --password mYstr0ngp4$$ --startup auto install
您也可以只 运行 命令和提升的提示,所以右键单击并 "Run-As_Administrator"。除非你必须运行在特定用户下。
我写了一个简单的 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)
服务本身没有问题,我的安装方法不对。正确的安装方式是
python aservice.py --username <username> --password <PASSWORD> --startup auto install
其中 <username>
如果使用本地帐户,则前缀为 .\
,如果使用域帐户,则前缀为 DOMAIN\
。
例如
python aservice.py --username .\johndoe --password mYstr0ngp4$$ --startup auto install
您也可以只 运行 命令和提升的提示,所以右键单击并 "Run-As_Administrator"。除非你必须运行在特定用户下。