I have a service for which I want to set Data value for FailureAction in registry. Currently there is value set in registry. Value is set using RegKey.SetValue("FailureActions", Value);
I would like to know:
1) How these bytes of Value correspond to recovery option of service (like how to find out particular sequence in registry means setting 'First failure' as 'Restart the Service')
2) Also I need to change in registry FailureAction which will correspond to 'Subsequent failures' as 'Restart the Service'
Here is my finding using trial and error method:
a)Manually change setting of recovery for service then registry entry changes. Copy that value and use in code. It set 'Subsequent failures'
b)Change original value in code. It set 'Subsequent failures'
But value from a) and b) does not match but I see same result if I right click on service and see recovery option. To understand this I would like to know answers to question 1) and 2).
Appreciate your comment\clue.
To explain the meaning of bytes in data value of FailureActions registry key, I will take this example:
The bytes in this representation correspond to this structure:
typedef struct _SERVICE_FAILURE_ACTIONS {
DWORD dwResetPeriod;
LPTSTR lpRebootMsg;
LPTSTR lpCommand;
DWORD cActions;
SC_ACTION *lpsaActions;
} SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS;
The first four bytes 80 51 01 00
are the value of dwResetPeriod
structure's member. It is the time after which to reset the failure count to zero if there are no failures. It is counted in seconds. In this example the reset period is 0x15180 sec (because of little endian). In decimal it is equivalent of 86400 sec or equal to 24 hours. So, if in a period of 24 hours there are no failures then the failure count is reset to zero.
The next four bytes 00 00 00 00
correspond to lpRebootMsg
. More info about this structure's member and the next one can be found here
The next four bytes 00 00 00 00
correspond to lpCommand
.
The next four bytes 03 00 00 00
correspond to cActions
. This member is the number of elements in the lpsaActions
array. In this case we have 3 elements.
The next four bytes 14 00 00 00
correspond to lpsaActions
which is a pointer to an array of type SA_ACTION
.
Finally, 01 00 00 00 60 EA 00 00
01 00 00 00 60 EA 00 00
00 00 00 00 00 00 00 00
is the content of an array of type SC_ACTION
pointed by lpsaActions
. We have 3 instances of this structure corresponding to the 3 lines of bytes. The structure SC_ACTION
is declared below:
typedef struct _SC_ACTION {
SC_ACTION_TYPE Type;
DWORD Delay;
} SC_ACTION, *LPSC_ACTION;
More info about SC_ACTION
and SC_ACTION_TYPE
can be found here.
So, first line 01 00 00 00 60 EA 00 00
means: : "In case of a failure, restart the service (01 00 00 00
) after 60 sec (60 EA 00 00
== to 0xEA60 ms == 60000 ms == 60 sec)." The second line means the same. The third line means "In case of failure, take no action(00 00 00 00
) after 0 sec (00 00 00 00
)"
How this works? Each time a service fails, the service controller increments a failure count N
and take the action N-1
specified in the array pointed by lpsaActions
. In our case, first time the service fails, N
is incremented to 1 and the controller will execute the actions indexed by 0
which means, restart the service after 60 sec. Second time it fails the N
is incremented to 2 and the action N-1 = 1
is taken which means, restart the service after 60 sec. The third time the service fails the controller executes the last action in array which in our case is, take no action. If N
is greater than cActions
, the service controller repeats the last action in the array. In this case the service is no started anymore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With