Actually, I think the trick is that you can't just use SC_ACTION_RUN_COMMAND. Here's what I did. It seemed to work for me...
Option Explicit
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const GENERIC_READ = &H80000000
Private Const ERROR_INSUFFICIENT_BUFFER = 122
Private Const SERVICE_NO_CHANGE = &HFFFFFFFF
Private Enum ServiceType
SERVICE_KERNEL_DRIVER = &H1
SERVICE_FILE_SYSTEM_DRIVER = &H2
SERVICE_WIN32_OWN_PROCESS = &H10
SERVICE_WIN32_SHARE_PROCESS = &H20
SERVICE_INTERACTIVE_PROCESS = &H100
SERVICETYPE_NO_CHANGE = SERVICE_NO_CHANGE
End Enum
Public Enum ServiceStartType
SERVICE_BOOT_START = &H0
SERVICE_SYSTEM_START = &H1
SERVICE_AUTO_START = &H2
SERVICE_DEMAND_START = &H3
SERVICE_DISABLED = &H4
SERVICESTARTTYPE_NO_CHANGE = SERVICE_NO_CHANGE
End Enum
Private Enum ServiceErrorControl
SERVICE_ERROR_IGNORE = &H0
SERVICE_ERROR_NORMAL = &H1
SERVICE_ERROR_SEVERE = &H2
SERVICE_ERROR_CRITICAL = &H3
msidbServiceInstallErrorControlVital = &H8000
SERVICEERRORCONTROL_NO_CHANGE = SERVICE_NO_CHANGE
End Enum
Private Enum ServiceStateRequest
SERVICE_ACTIVE = &H1
SERVICE_INACTIVE = &H2
SERVICE_STATE_ALL = (SERVICE_ACTIVE + SERVICE_INACTIVE)
End Enum
Private Enum ServiceControlType
SERVICE_CONTROL_STOP = &H1
SERVICE_CONTROL_PAUSE = &H2
SERVICE_CONTROL_CONTINUE = &H3
SERVICE_CONTROL_INTERROGATE = &H4
SERVICE_CONTROL_SHUTDOWN = &H5
SERVICE_CONTROL_PARAMCHANGE = &H6
SERVICE_CONTROL_NETBINDADD = &H7
SERVICE_CONTROL_NETBINDREMOVE = &H8
SERVICE_CONTROL_NETBINDENABLE = &H9
SERVICE_CONTROL_NETBINDDISABLE = &HA
SERVICE_CONTROL_DEVICEEVENT = &HB
SERVICE_CONTROL_HARDWAREPROFILECHANGE = &HC
SERVICE_CONTROL_POWEREVENT = &HD
SERVICE_CONTROL_SESSIONCHANGE = &HE
End Enum
Private Enum ServiceState
SERVICE_STOPPED = &H1
SERVICE_START_PENDING = &H2
SERVICE_STOP_PENDING = &H3
SERVICE_RUNNING = &H4
SERVICE_CONTINUE_PENDING = &H5
SERVICE_PAUSE_PENDING = &H6
SERVICE_PAUSED = &H7
End Enum
Private Enum ServiceControlAccepted
SERVICE_ACCEPT_STOP = &H1
SERVICE_ACCEPT_PAUSE_CONTINUE = &H2
SERVICE_ACCEPT_SHUTDOWN = &H4
SERVICE_ACCEPT_PARAMCHANGE = &H8
SERVICE_ACCEPT_NETBINDCHANGE = &H10
SERVICE_ACCEPT_HARDWAREPROFILECHANGE = &H20
SERVICE_ACCEPT_POWEREVENT = &H40
SERVICE_ACCEPT_SESSIONCHANGE = &H80
End Enum
Private Enum ServiceControlManagerType
SC_MANAGER_CONNECT = &H1
SC_MANAGER_CREATE_SERVICE = &H2
SC_MANAGER_ENUMERATE_SERVICE = &H4
SC_MANAGER_LOCK = &H8
SC_MANAGER_QUERY_LOCK_STATUS = &H10
SC_MANAGER_MODIFY_BOOT_CONFIG = &H20
SC_MANAGER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED + SC_MANAGER_CONNECT + SC_MANAGER_CREATE_SERVICE + SC_MANAGER_ENUMERATE_SERVICE + SC_MANAGER_LOCK + SC_MANAGER_QUERY_LOCK_STATUS + SC_MANAGER_MODIFY_BOOT_CONFIG)
End Enum
Private Enum ACCESS_TYPE
SERVICE_QUERY_CONFIG = &H1
SERVICE_CHANGE_CONFIG = &H2
SERVICE_QUERY_STATUS = &H4
SERVICE_ENUMERATE_DEPENDENTS = &H8
SERVICE_START = &H10
SERVICE_STOP = &H20
SERVICE_PAUSE_CONTINUE = &H40
SERVICE_INTERROGATE = &H80
SERVICE_USER_DEFINED_CONTROL = &H100
SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED + SERVICE_QUERY_CONFIG + SERVICE_CHANGE_CONFIG + SERVICE_QUERY_STATUS + SERVICE_ENUMERATE_DEPENDENTS + SERVICE_START + SERVICE_STOP + SERVICE_PAUSE_CONTINUE + SERVICE_INTERROGATE + SERVICE_USER_DEFINED_CONTROL)
End Enum
Private Type SERVICE_STATUS
dwServiceType As Long
dwCurrentState As Long
dwControlsAccepted As Long
dwWin32ExitCode As Long
dwServiceSpecificExitCode As Long
dwCheckPoint As Long
dwWaitHint As Long
End Type
Private Type QUERY_SERVICE_CONFIG
dwServiceType As Long
dwStartType As Long
dwErrorControl As Long
lpBinaryPathName As Long
lpLoadOrderGroup As Long
dwTagId As Long
lpDependencies As Long
lpServiceStartName As Long
lpDisplayName As Long
End Type
Private Enum SC_ACTION_TYPE
SC_ACTION_NONE = 0
SC_ACTION_RESTART = 1
SC_ACTION_REBOOT = 2
SC_ACTION_RUN_COMMAND = 3
End Enum
Private Type SC_ACTION
SCActionType As SC_ACTION_TYPE
Delay As Long
End Type
Private Enum InfoLevel
SERVICE_CONFIG_DESCRIPTION = 1
SERVICE_CONFIG_FAILURE_ACTIONS = 2
End Enum
Private Type SERVICE_DESCRIPTIONW
lpDescription As Long
End Type
Private Type SERVICE_FAILURE_ACTIONSW
dwResetPeriod As Long
lpRebootMsg As Long
lpCommand As Long
cActions As Long
lpsaActions() As SC_ACTION
End Type
Private Declare Function CloseServiceHandle Lib "advapi32.dll" (ByVal hSCObject As Long) As Long
Private Declare Function QueryServiceStatus Lib "advapi32.dll" (ByVal hService As Long, lpServiceStatus As SERVICE_STATUS) As Long
Private Declare Function QueryServiceStatusEx Lib "advapi32.dll" (ByVal hService As Long, ByVal InfoLevel As Long, lpBuffer As Byte, ByVal cbBufSize As Long, pcbBytesNeeded As Long) As Long
Private Declare Function StartService Lib "advapi32.dll" Alias "StartServiceW" (ByVal hService As Long, ByVal dwNumServiceArgs As Long, ByVal lpServiceArgVectors As Long) As Long
Private Declare Function ControlService Lib "advapi32.dll" (ByVal hService As Long, ByVal dwControl As ServiceControlType, lpServiceStatus As SERVICE_STATUS) As Long
Private Declare Function ChangeServiceConfig Lib "advapi32.dll" Alias "ChangeServiceConfigW" (ByVal hService As Long, ByVal dwServiceType As ServiceType, ByVal dwStartType As ServiceStartType, ByVal dwErrorControl As ServiceErrorControl, ByVal lpBinaryPathName As Long, ByVal lpLoadOrderGroup As Long, lpdwTagId As Long, ByVal lpDependencies As Long, ByVal lpServiceStartName As Long, ByVal lpPassword As Long, ByVal lpDisplayName As Long) As Long
Private Declare Function ChangeServiceConfig2 Lib "advapi32.dll" Alias "ChangeServiceConfig2W" (ByVal hService As Long, ByVal dwInfoLevel As InfoLevel, lpInfo As Any) As Boolean
Private Declare Function OpenService Lib "advapi32.dll" Alias "OpenServiceA" (ByVal hSCManager As Long, ByVal lpServiceName As String, ByVal dwDesiredAccess As ACCESS_TYPE) As Long
Private Declare Function OpenSCManager Lib "advapi32.dll" Alias "OpenSCManagerA" (ByVal lpMachineName As String, ByVal lpDatabaseName As String, ByVal dwDesiredAccess As ServiceControlManagerType) As Long
Private Declare Function QueryServiceConfig Lib "advapi32.dll" Alias "QueryServiceConfigA" (ByVal hService As Long, lpServiceConfig As Byte, ByVal cbBufSize As Long, pcbBytesNeeded As Long) As Long
Private Declare Function LockServiceDatabase Lib "advapi32.dll" (ByVal hSCManager As Long) As Long
Private Declare Function UnlockServiceDatabase Lib "advapi32.dll" (ByVal ScLock As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Public Function ChangeRecoveryNow(ServiceName As String, Optional SystemName As String) As String
Dim hSCM As Long
Dim hSVC As Long
Dim LockDB As Long
Dim pSTATUS As SERVICE_STATUS
Dim Result As Long
Dim IPInfo As SERVICE_FAILURE_ACTIONSW
Dim SCAction(0) As SC_ACTION
Err.Clear
With SCAction(0)
.Delay = 60000
.SCActionType = SC_ACTION_RESTART
End With
With IPInfo
.dwResetPeriod = 0
'.lpRebootMsg =
'.lpCommand =
.cActions = 1
.lpsaActions = SCAction
End With
hSCM = OpenSCManager(SystemName, vbNullString, SC_MANAGER_ALL_ACCESS)
If hSCM = 0 Then
ChangeRecoveryNow = ErrorCode(Err.LastDllError)
Exit Function
End If
LockDB = LockServiceDatabase(hSCM)
If LockDB = 0 Then
ChangeRecoveryNow = ErrorCode(Err.LastDllError)
Exit Function
End If
hSVC = OpenService(hSCM, ServiceName, SERVICE_ALL_ACCESS)
If hSVC = 0 Then
ChangeRecoveryNow = ErrorCode(Err.LastDllError)
GoTo CloseHandles
End If
Result = ChangeServiceConfig2(hSVC, SERVICE_CONFIG_FAILURE_ACTIONS, IPInfo)
If Result = 0 Then
ChangeRecoveryNow = ErrorCode(Err.LastDllError)
Else
ChangeRecoveryNow = "Success"
End If
CloseHandles:
UnlockServiceDatabase (LockDB)
CloseServiceHandle (hSVC)
CloseServiceHandle (hSCM)
End Function
Let me know if this works for you...
Carlos