views:

77

answers:

2

Hi, I need some help with a python service.

I have a service written in Python. What I need to do is to pass it some arguments. Let me give you an example to explain it a bit better.

Lets say I have a service, that does nothing but writes something to a log. I'd like to write the same thing into the log several times, so I use a loop. I would like to pass the counter for the loop when I start the service, but I have no idea how. I start the service with:

win32serviceutil.HandleCommandLine(WinService)

I'm looking for something like

win32serviceutil.HandleCommandLine(WinService,10)

I don't really care how its done, as long as I can pass arguments to it. Have been trying to get this to work for the better part of the day with no luck. Also, the service isn't run directly, but is imported and then run from there.

EDIT:

Here is an example, hopefully it will clear some things up.

This is in 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)

This is in the main script:

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

As it is now, the loop will execute a fixed amount of times. What I would like is to simply send the value to the service somehow. Don't really care how.

A: 

Sorry, not enough info to answer your question. This seem an application-specific thing.

The only thing I can think is to review the code of win32serviceutil.HandleCommandLine method and WinService class to determine which one writes to the log. Then, you have to make a subclass and override the method responsible to write in the log to receive an additional argument. Finally, you must chance all references from the original class to the new one.

-- Added, after the edition of the question.

Clearer, but still insufficient. You need to review win32serviceutil.HandleCommandLine and see how it invokes service.WindowsService.LoopService._init_. In particular, how HandleCommandLine generates args and how you can control it.

If you are in a hurry, you can do:

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)

Then you can control the number of repetition changing LoopService.repetitions before creating a new instance.

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

This works, but it's ugly. Try to control args and then set self.repetition accordingly.

jdinuncio
I've edited my post to include an example that will hopefully give more info.
Grim
A: 

I don't think you can pass argument directly to the service. You can probably use the environment (set environment variable before starting the service and read it from the service).

lazy1