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"。除非你必须运行在特定用户下。