当尝试使用ControlServiceEx函数停止Windows服务时,我收到错误122 ERROR_INSUFFICIENT_BUFFER。
我有以下实现:
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function OpenSCManager(ByVal machineName As String, ByVal databaseName As String, ByVal desiredAccess As ScmAccessRights) As IntPtr
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
Public Shared Function QueryServiceStatusEx(hService As IntPtr, infoLevel As Integer, lpBuffer As IntPtr, cbBufSize As Integer, ByRef pcbBytesNeeded As Integer) As Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True)>
Private Shared Function ControlServiceEx(hService As IntPtr, dwControl As ServiceControl, dwInfoLevel As Integer, ByRef pControlParams As SERVICE_CONTROL_STATUS_REASON_PARAMS) As Integer
End Function
Private Shared Sub StopService(service As IntPtr)
Dim Status As SERVICE_STATUS_PROCESS
Status = QueryServiceStatusEx(service)
If Status.dwCurrentState <> ServiceState.ServiceStopped AndAlso Status.dwCurrentState <> ServiceState.NotFound Then
Dim ScStatusReasonInfoParam As New SERVICE_CONTROL_STATUS_REASON_PARAMS
ScStatusReasonInfoParam.dwReason = ServiceStopReason.ServicePlannedStop
ScStatusReasonInfoParam.ServiceStatus = Status ' New SERVICE_STATUS_PROCESS
Dim Res = ControlServiceEx(service, ServiceControl.[Stop], SERVICE_CONTROL_STATUS_REASON_INFO, ScStatusReasonInfoParam)
Dim ChangedStatus = WaitForServiceStatus(service, ServiceState.ServiceStopPending, ServiceState.ServiceStopped)
If Not ChangedStatus Then
Dim winError = New Win32Exception(Marshal.GetLastWin32Error())
Throw New ApplicationException("Unable to stop service", winError)
End If
End If
End Sub
Public Shared Function QueryServiceStatusEx(serviceHandle As IntPtr) As SERVICE_STATUS_PROCESS
Dim buf As IntPtr = IntPtr.Zero
Try
Dim size As Integer = 0
QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO, buf, size, size)
buf = Marshal.AllocHGlobal(size)
If Not QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO, buf, size, size) Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If
Return DirectCast(Marshal.PtrToStructure(buf, GetType(SERVICE_STATUS_PROCESS)), SERVICE_STATUS_PROCESS)
Finally
If Not buf.Equals(IntPtr.Zero) Then
Marshal.FreeHGlobal(buf)
End If
End Try
End Function
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure SERVICE_STATUS_PROCESS
Public dwServiceType As ServiceTypeFlag
Public dwCurrentState As ServiceState
Public dwControlsAccepted As Integer
Public dwWin32ExitCode As Integer
Public dwServiceSpecificExitCode As Integer
Public dwCheckPoint As Integer
Public dwWaitHint As Integer
Public dwProcessID As Integer
Public dwServiceFlags As Integer
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure SERVICE_CONTROL_STATUS_REASON_PARAMS
Public dwReason As Integer
<MarshalAs(UnmanagedType.LPTStr)> Public pszComment As String 'string
Public ServiceStatus As SERVICE_STATUS_PROCESS
End Structure
Public Enum ServiceStopReason
SERVICE_STOP_REASON_FLAG_PLANNED = &H40000000
SERVICE_STOP_REASON_MAJOR_NONE = &H60000
SERVICE_STOP_REASON_MINOR_NONE = &H60000
ServicePlannedStop = (SERVICE_STOP_REASON_FLAG_PLANNED Or SERVICE_STOP_REASON_MAJOR_NONE Or SERVICE_STOP_REASON_MINOR_NONE)
End Enum
我哪里错了?