manipulating service action restart behavior?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

manipulating service action restart behavior?

Andrew Hammond
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 list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Reply | Threaded
Open this post in threaded view
|

Re: manipulating service action restart behavior?

Andrew Hammond
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 <[hidden email]> 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 list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Reply | Threaded
Open this post in threaded view
|

Re: manipulating service action restart behavior?

Randy Syring-2
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 <[hidden email]> 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 list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32

_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Reply | Threaded
Open this post in threaded view
|

Re: manipulating service action restart behavior?

Andrew Hammond
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 <[hidden email]> 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: <a href="tel:502-276-0459" value="+15022760459" target="_blank">502-276-0459
Office: <a href="tel:502-212-9913" value="+15022129913" target="_blank">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 <[hidden email]> 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 list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32


_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Reply | Threaded
Open this post in threaded view
|

Re: manipulating service action restart behavior?

Howard Lightstone


On Wed, Aug 10, 2011 at 1:54 PM, Andrew Hammond <[hidden email]> wrote:
Bingo! Thanks very much!!!

A


On Wed, Aug 10, 2011 at 12:54 PM, Howard Lightstone <[hidden email]> wrote:
Maybe because sfa_keys thinks the correct key is "Command" and not "lpCommand"?


Sorry, in haste, I forgot to post this to the list for future searches.

--
Howard Lightstone
[hidden email]

_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Reply | Threaded
Open this post in threaded view
|

Re: manipulating service action restart behavior?

Andrew Hammond
In reply to this post by Andrew Hammond
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 <[hidden email]> 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 <[hidden email]> 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: <a href="tel:502-276-0459" value="+15022760459" target="_blank">502-276-0459
Office: <a href="tel:502-212-9913" value="+15022129913" target="_blank">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 <[hidden email]> 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 list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32



_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32

correct_ChangeServiceConfig2_error_message.patch (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: manipulating service action restart behavior?

python@bdurham.com
Andrew,
 
Thanks for sharing the solution!
 
Regards,
Malcolm
 

_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Reply | Threaded
Open this post in threaded view
|

Re: manipulating service action restart behavior?

Mark Hammond-4
In reply to this post by Andrew Hammond
On 11/08/2011 7:31 AM, Andrew Hammond wrote:
...
> I suggest the attached patch to correct the error message.

Excellent, thanks!  I checked it in.

Cheers,

Mark
_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32