[python-win32] manipulating service action restart behavior?

Andrew Hammond andrew.george.hammond at gmail.com
Wed Aug 10 23:31:23 CEST 2011


Howard Lightstone pointed out that sfa_keys thinks that the correct key is
"Command" not "lpCommand" as the error message says. Working code follows:

    hscm =
win32service.OpenSCManager(None,None,win32service.SC_MANAGER_ALL_ACCESS)
    try:
        hs = win32serviceutil.SmartOpenService(hscm, svc_name,
win32service.SERVICE_ALL_ACCESS)
        try:
            service_failure_actions = {
                'ResetPeriod': 6000000,     # Time in ms after which to
reset the failure count to zero.
                'RebootMsg': u'',           # Not using reboot option
                'Command': u'',             # Not using run-command option
                'Actions': [
                        (win32service.SC_ACTION_RESTART, 60000),    #
action, delay in ms
                        (win32service.SC_ACTION_RESTART, 60000)
                    ]
            }
            win32service.ChangeServiceConfig2(hs,
win32service.SERVICE_CONFIG_FAILURE_ACTIONS, service_failure_actions)
        finally:
            win32service.CloseServiceHandle(hs)
    finally:
        win32service.CloseServiceHandle(hscm)

I suggest the attached patch to correct the error message.

Andrew


On Wed, Aug 10, 2011 at 12:08 PM, Andrew Hammond <
andrew.george.hammond at gmail.com> wrote:

> I tried that change and get the exact same error message. I found the code
> sending the error message in pywin32/win32/src/win32service.i
> I've extracted what I think are the relevant snippets:
>
> 1675         // @flag SERVICE_CONFIG_FAILURE_ACTIONS|Dict representing a
> SERVICE_FAILURE_ACTIONS struct
> 1676         case SERVICE_CONFIG_FAILURE_ACTIONS:{
> 1677             SERVICE_FAILURE_ACTIONSW buf;
> 1678             if (!PyWinObject_AsSERVICE_FAILURE_ACTIONS(obinfo, &buf))
> 1679                 return NULL;
> 1680             bsuccess=(*fpChangeServiceConfig2)(hService, level,
> (LPVOID)&buf);
> 1681             PyWinObject_FreeSERVICE_FAILURE_ACTIONS(&buf);
> 1682             break;
> 1683             }
>
> Which calls into  this:
>
> 1584 BOOL PyWinObject_AsSERVICE_FAILURE_ACTIONS(PyObject *obinfo,
> LPSERVICE_FAILURE_ACTIONSW psfa)
> 1585 {
> 1586     static char
> *sfa_keys[]={"ResetPeriod","RebootMsg","Command","Actions",0};
> 1587     static char *err="SERVICE_FAILURE_ACTIONS must be a dictionary
> containing
> {'ResetPeriod':int,'RebootMsg':unicode,'lpCommand':unicode,'Actions':sequence
> of 2 tuples(int,int)";
> 1588     PyObject *dummy_tuple, *obActions, *obRebootMsg, *obCommand;
> 1589     BOOL ret;
> 1590     ZeroMemory(psfa, sizeof(SERVICE_FAILURE_ACTIONSW));
> 1591     if (!PyDict_Check(obinfo)){
> 1592         PyErr_SetString(PyExc_TypeError,err);
> 1593         return FALSE;
> 1594         }
> 1595     dummy_tuple=PyTuple_New(0);
> 1596     if (dummy_tuple==NULL)
> 1597         return FALSE;
> 1598     ret=PyArg_ParseTupleAndKeywords(dummy_tuple, obinfo,
> "lOOO:SERVICE_FAILURE_ACTIONS", sfa_keys,
> 1599         &psfa->dwResetPeriod, &obRebootMsg, &obCommand, &obActions);
> 1600     Py_DECREF(dummy_tuple);
> 1601     if (!ret){
> 1602         PyErr_Clear();
> 1603         PyErr_SetString(PyExc_TypeError,err);
> 1604         return FALSE;
> 1605         }
> 1606     if (PyWinObject_AsWCHAR(obRebootMsg, &psfa->lpRebootMsg, TRUE)
> 1607         &&PyWinObject_AsWCHAR(obCommand,   &psfa->lpCommand,   TRUE)
> 1608         &&PyWinObject_AsSC_ACTIONS(obActions,&psfa->lpsaActions,
> &psfa->cActions))
> 1609         return TRUE;
> 1610     PyWinObject_FreeSERVICE_FAILURE_ACTIONS(psfa);
> 1611     return FALSE;
> 1612 }
>
> So, I'm confused because I think I'm correctly passing it a dict object,
> yet it appears that PyDict_Check is disagreeing and saying that it is not a
> dict object. What am I missing?
>
> A
>
>
>
>
> On Tue, Aug 9, 2011 at 7:27 PM, Randy Syring <rsyring at gmail.com> wrote:
>
>>  This is a shot in the dark, but if you are on python 2, then:
>>
>>             'RebootMsg': '',
>>             'lpCommand': '',
>>
>> Is two strings, not unicode.  Maybe:
>>
>>             'RebootMsg': u'',
>>             'lpCommand': u'',
>>
>>
>> --------------------------------------
>> Randy Syring
>> Intelicom
>> Direct: 502-276-0459
>> Office: 502-212-9913
>>
>> For the wages of sin is death, but the
>> free gift of God is eternal life in
>> Christ Jesus our Lord (Rom 6:23)
>>
>>
>> On 08/09/2011 08:56 PM, Andrew Hammond wrote:
>>
>> I did some more hunting around and now have the following:
>>
>>  hscm =
>> win32service.OpenSCManager(None,None,win32service.SC_MANAGER_ALL_ACCESS)
>> try:
>>     hs = win32serviceutil.SmartOpenService(hscm, cls._svc_name_,
>> win32service.SERVICE_ALL_ACCESS)
>>     try:
>>         service_failure_actions = {
>>             'ResetPeriod': 6000000,   # Time in seconds after which to
>> reset the failure count to zero.
>>             'RebootMsg': '',
>>             'lpCommand': '',
>>             'Actions': [(win32service.SC_ACTION_RESTART, 60000),
>> (win32service.SC_ACTION_RESTART, 60000)]
>>         }
>>         win32service.ChangeServiceConfig2(hs,
>> win32service.SERVICE_CONFIG_FAILURE_ACTIONS, service_failure_actions)
>>     finally:
>>         win32service.CloseServiceHandle(hs)
>> finally:
>>     win32service.CloseServiceHandle(hscm)
>>
>>  However, I'm getting the following error message:
>>
>>  TypeError: SERVICE_FAILURE_ACTIONS must be a dictionary containing
>> {'ResetPeriod':int,'RebootMsg':unicode,'lpCommand':unicode,'Actions':sequence
>> of 2 tuples(int,int)
>>
>>  Which I think is what I'm feeding it. Can someone please tell me what
>> I'm doing wrong?
>>
>>  A
>>
>> On Mon, Aug 8, 2011 at 7:06 PM, Andrew Hammond <
>> andrew.george.hammond at gmail.com> wrote:
>>
>>> I am trying to control the behavior of a service with regards to failure
>>> handling as described here:
>>> http://blogs.msdn.com/b/jcalev/archive/2008/01/10/some-tricks-with-service-restart-logic.aspx
>>>
>>>  I have done some reading and have the following snippet of code that I
>>> think is going in the right direction. However I don't know how to create
>>> the action list. I suspect that it should be an array of unsigned long ints,
>>> but... ???
>>>
>>>
>>>          hscm =
>>> win32service.OpenSCManager(None,None,win32service.SC_MANAGER_ALL_ACCESS)
>>>
>>>          try:
>>>             hs = SmartOpenService(hscm, cls._svc_name_,
>>> win32service.SERVICE_ALL_ACCESS)
>>>             try:
>>>                 # What's the pythonic way to create these???
>>>                 action1 = Action()
>>>                 action1.Type = win32service.SC_ACTION_RESTART
>>>                 action1.Delay = 600  # 10 minutes?
>>>
>>>                  action2 = Action()
>>>                 action2.Type = win32service.SC_ACTION_RESTART
>>>                 action2.Delay = 600
>>>
>>>                  action3 = Action()
>>>                 action3.Type = win32service.SC_ACTION_RESTART
>>>                 action3.Delay = 600
>>>
>>>                  win32service.ChangeServiceConfig2(
>>>                     hs,
>>>                     win32service.SERVICE_CONFIG_FAILURE_ACTIONS,
>>>                     [action1,action2,action3]  # again, this isn't
>>> probably right, but... ?
>>>                 )
>>>             finally:
>>>                 win32service.CloseServiceHandle(hs)
>>>         finally:
>>>             win32service.CloseServiceHandle(hscm)
>>>
>>>  Can anyone help please?
>>>
>>>  Andrew
>>>
>>
>>
>>
>> _______________________________________________
>> python-win32 mailing listpython-win32 at python.orghttp://mail.python.org/mailman/listinfo/python-win32
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-win32/attachments/20110810/d4036839/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: correct_ChangeServiceConfig2_error_message.patch
Type: application/octet-stream
Size: 847 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-win32/attachments/20110810/d4036839/attachment-0001.obj>


More information about the python-win32 mailing list