将参数传递给Python服务

3 投票
2 回答
4634 浏览
提问于 2025-04-15 23:42

我需要一些关于Python服务的帮助。

我有一个用Python写的服务。我需要做的是给它传递一些参数。让我举个例子,帮助你更好地理解。

假设我有一个服务,它的功能就是往日志里写东西。我想把同样的内容写入日志多次,所以我使用了一个循环。我希望在启动服务时传递循环的计数器,但我不知道该怎么做。我是这样启动服务的:

win32serviceutil.HandleCommandLine(WinService)

我想要的类似于

win32serviceutil.HandleCommandLine(WinService,10)

我并不在乎具体怎么实现,只要我能给它传递参数就行。我今天花了大部分时间尝试让这个工作,但一直没有成功。而且,这个服务不是直接运行的,而是被导入后再运行。

编辑:

这里有一个例子,希望能澄清一些事情。

这是在WindowsService.py文件中的内容:

import win32serviceutil, win32service, win32event, servicemanager, win32serviceutil

class LoopService(win32serviceutil.ServiceFramework):
    _svc_name_ = "LoopService"
    _svc_description_ = "LoopService"
    _svc_display_name_ = "LoopService" 

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING);
        win32event.SetEvent(self.hWaitStop);

    def SvcDoRun(self):
        i = 0;
        while i < 5:
            servicemanager.LogInfoMsg("just something to put in the log");
            i += 1
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

这是在主脚本中的内容:

import service.WindowsService, win32serviceutil
win32serviceutil.HandleCommandLine(service.WindowsService.LoopService);

现在这样的话,循环会执行固定次数。我想要的只是以某种方式把这个值发送给服务。具体怎么做我并不在乎。

2 个回答

0

抱歉,信息不够,无法回答你的问题。这似乎是一个特定应用的问题。

我能想到的唯一办法是查看win32serviceutil.HandleCommandLine方法和WinService类的代码,看看哪个部分负责写日志。然后,你需要创建一个子类,并重写负责写日志的方法,以便接收一个额外的参数。最后,你必须把所有原来指向原始类的地方都改成指向新类。

-- 在问题编辑后添加。

更清楚了,但还是不够。你需要查看win32serviceutil.HandleCommandLine,看看它是如何调用service.WindowsService.LoopService.__init__的。特别是,HandleCommandLine是如何生成args的,以及你如何控制它。

如果你很着急,可以这样做:

class LoopService(win32serviceutil.ServiceFramework):
    repetitions = 5
    # ... 

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)
        self.repetitions = LoopService.repetitions

    # ...

    def SvcDoRun(self):
        for i in range(self.repetitions):
            servicemanager.LogInfoMsg("just something to put in the log");
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

然后你可以在创建新实例之前,通过改变LoopService.repetitions来控制重复的次数。

import service.WindowsService, win32serviceutil
service.WindowsService.LoopService.repetitions = 10
win32serviceutil.HandleCommandLine(service.WindowsService.LoopService);

这样做是可行的,但看起来不太好。试着控制args,然后相应地设置self.repetition

0

我觉得你不能直接把参数传给服务。你可以试试使用环境变量,也就是在启动服务之前设置好环境变量,然后在服务里读取这些变量。

撰写回答