用Python编写的Windows服务仅在调试模式下工作。

6
我已经编写了一个简单的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附加到终端,因此您的服务代码可能会尝试将输出发送到其中之一,但由于在非调试模式下它们不存在,因此该尝试仅在以该模式运行时才会导致致命错误。 - martineau
嗯,我的服务没有标准输出,它只创建了一个 WebSocket 连接并将一些数据发送到远程服务器。我编辑了代码,将这些数据写入文件,和以前一样,只有在调试模式下运行服务时,文件才会被写入。 - ivica
1
可能会有一些东西被写入到stderr中...例如来自未处理的异常。也许你需要加强服务的错误处理,使用一些扩展的try/except子句。 - martineau
2个回答

2

服务本身运行良好,我的安装方法有误。正确的安装方式是:

python aservice.py  --username <username> --password <PASSWORD> --startup auto install

如果使用本地账户,则在<username>前加上.\;如果使用域账户,则在<username>前加上DOMAIN\

例如:

python aservice.py  --username .\johndoe --password mYstr0ngp4$$ --startup auto install

0

您也可以从提升的提示符中运行命令,右键单击并选择“以管理员身份运行”。除非您必须在特定用户下运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接