tatane Posted May 14, 2018 Posted May 14, 2018 (edited) Hi, Sorry this post is a copy of this one but i've got no answer :-( I would like to use ChangeServiceConfig2 function to set recovery properties of a Windows service but it doesn't work. https://msdn.microsoft.com/en-us/library/windows/desktop/ms681988(v=vs.85).aspx I'm using _Service_UDF v4 library. Here is my code : expandcollapse popupFunc _ChangeServiceConfig2($sServiceName, $sComputerName = "") Local $hSC, $hService, $rdll $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT) $hService = OpenService($hSC, $sServiceName, $SERVICE_CHANGE_CONFIG) ;~ typedef struct _SERVICE_FAILURE_ACTIONS { ;~ DWORD dwResetPeriod; ;~ LPTSTR lpRebootMsg; ;~ LPTSTR lpCommand; ;~ DWORD cActions; ;~ SC_ACTION *lpsaActions; ;~ } SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS; ;~ typedef struct _SC_ACTION { ;~ SC_ACTION_TYPE Type; ;~ DWORD Delay; ;~ } SC_ACTION, *LPSC_ACTION; Local $SC_ACTION_NONE = 0 Local $SC_ACTION_REBOOT = 2 Local $SC_ACTION_RESTART = 1 Local $SC_ACTION_RUN_COMMAND = 3 Local $SERVICE_CONFIG_FAILURE_ACTIONS = 2 Local $sc_action = DllStructCreate("int Type; DWORD Delay") DllStructSetData($sc_action, "Type", $SC_ACTION_RESTART) DllStructSetData($sc_action, "Delay", 1000) Local Const $sTagSC_ACTION = "int;dword" Local $iNumberOfArrayElement = 1 Local $tArraySC_ACTION = DllStructCreate($sTagSC_ACTION) DllStructSetData($tArraySC_ACTION, 1, $SC_ACTION_RESTART) DllStructSetData($tArraySC_ACTION, 2, 10000) Local $PtrSC_ACTION_Array = DllStructGetPtr($tArraySC_ACTION) Local $serviceFailureActions = DllStructCreate("DWORD dwResetPeriod;ptr lpRebootMsg;ptr lpCommand;DWORD cActions;ptr lpsaActions") DllStructSetData($serviceFailureActions, "dwResetPeriod", "INFINITE") Local $lpRebootMsg = DllStructCreate("wstr") DllStructSetData($lpRebootMsg, 1, "") DllStructSetData($serviceFailureActions, "lpRebootMsg", DllStructGetPtr($lpRebootMsg)) DllStructSetData($serviceFailureActions, "lpCommand", Null) DllStructSetData($serviceFailureActions, "cActions", $iNumberOfArrayElement) DllStructSetData($serviceFailureActions, "lpsaActions", $PtrSC_ACTION_Array) Local $dwInfoLevel = $SERVICE_CONFIG_FAILURE_ACTIONS Local $lpInfo = DllStructGetPtr($serviceFailureActions) $rdll = DllCall($hAdvapi32_DLL, "BOOLEAN", "ChangeServiceConfig2", _ "HANDLE", $hService, _ "DWORD", $dwInfoLevel, _ "ptr", $lpInfo) ; pointeur vers la structure SERVICE_FAILURE_ACTIONS CloseServiceHandle($hService) CloseServiceHandle($hSC) If @error Then Return 0 Else Return $rdll[0] EndIf EndFunc I suppose my problem coming from the "lpsaActions" variable. It should be a pointer to array of Service_Failure_Actions structures. Any idea ? Thanks and sorry for the double post. P.S : I know I can use some SC command but I would prefer Windows internal function. Edited May 16, 2018 by tatane
tatane Posted May 16, 2018 Author Posted May 16, 2018 Ok I found what was the problem... We have to Run the script with admin privilege. (#RequireAdmin) Here is the function to set the service failure parameters : expandcollapse popupFunc _ChangeServiceConfig2($sServiceName, $sComputerName = "") Local $hSC, $hService, $rdll $hSC = OpenSCManager($sComputerName, $SC_MANAGER_ALL_ACCESS) $hService = OpenService($hSC, $sServiceName, $SERVICE_ALL_ACCESS) ;~ typedef struct _SERVICE_FAILURE_ACTIONS { ;~ DWORD dwResetPeriod; ;~ LPTSTR lpRebootMsg; ;~ LPTSTR lpCommand; ;~ DWORD cActions; ;~ SC_ACTION *lpsaActions; ;~ } SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS; ;~ typedef struct _SC_ACTION { ;~ SC_ACTION_TYPE Type; see below ;~ DWORD Delay; in ms ;~ } SC_ACTION, *LPSC_ACTION; Local $SC_ACTION_NONE = 0 Local $SC_ACTION_REBOOT = 2 Local $SC_ACTION_RESTART = 1 Local $SC_ACTION_RUN_COMMAND = 3 Local $SERVICE_CONFIG_FAILURE_ACTIONS = 2 Local $sc_action = DllStructCreate("int Type; DWORD Delay") DllStructSetData($sc_action, "Type", $SC_ACTION_RESTART) DllStructSetData($sc_action, "Delay", 1000) Local Const $sTagSC_ACTION = "int;dword;int;dword;int;dword" Local $iNumberOfArrayElement = 3 Local $tArraySC_ACTION = DllStructCreate($sTagSC_ACTION) DllStructSetData($tArraySC_ACTION, 1, $SC_ACTION_RESTART) DllStructSetData($tArraySC_ACTION, 2, 60000) DllStructSetData($tArraySC_ACTION, 3, $SC_ACTION_RESTART) DllStructSetData($tArraySC_ACTION, 4, 60000) DllStructSetData($tArraySC_ACTION, 5, $SC_ACTION_RESTART) DllStructSetData($tArraySC_ACTION, 6, 60000) Local $PtrSC_ACTION_Array = DllStructGetPtr($tArraySC_ACTION) Local $serviceFailureActions = DllStructCreate("DWORD dwResetPeriod;uint_ptr lpRebootMsg;uint_ptr lpCommand;DWORD cActions;uint_ptr lpsaActions") DllStructSetData($serviceFailureActions, "dwResetPeriod", 86400) Local $lpRebootMsg = DllStructCreate("wstr") DllStructSetData($lpRebootMsg, 1, "") DllStructSetData($serviceFailureActions, "lpRebootMsg", DllStructGetPtr($lpRebootMsg)) DllStructSetData($serviceFailureActions, "lpCommand", Null) DllStructSetData($serviceFailureActions, "cActions", $iNumberOfArrayElement) DllStructSetData($serviceFailureActions, "lpsaActions", $PtrSC_ACTION_Array) Local $dwInfoLevel = $SERVICE_CONFIG_FAILURE_ACTIONS Local $lpInfo = DllStructGetPtr($serviceFailureActions) $rdll = DllCall($hAdvapi32_DLL, "int", "ChangeServiceConfig2", _ "HANDLE", $hService, _ "DWORD", $dwInfoLevel, _ "ptr", $lpInfo) ; pointeur vers la structure SERVICE_FAILURE_ACTIONS CloseServiceHandle($hService) CloseServiceHandle($hSC) If @error Then Return 0 Else Return $rdll[0] EndIf EndFunc
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now