[StructLayout(LayoutKind.Sequential)]
internal sealed class SERVICE_STATUS_PROCESS
{
[MarshalAs(UnmanagedType.U4)]
public uint dwServiceType;
[MarshalAs(UnmanagedType.U4)]
public uint dwCurrentState;
[MarshalAs(UnmanagedType.U4)]
public uint dwControlsAccepted;
[MarshalAs(UnmanagedType.U4)]
public uint dwWin32ExitCode;
[MarshalAs(UnmanagedType.U4)]
public uint dwServiceSpecificExitCode;
[MarshalAs(UnmanagedType.U4)]
public uint dwCheckPoint;
[MarshalAs(UnmanagedType.U4)]
public uint dwWaitHint;
[MarshalAs(UnmanagedType.U4)]
public uint dwProcessId;
[MarshalAs(UnmanagedType.U4)]
public uint dwServiceFlags;
}
internal const int ERROR_INSUFFICIENT_BUFFER = 0x7a;
internal const int SC_STATUS_PROCESS_INFO = 0;
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool QueryServiceStatusEx(SafeHandle hService, int infoLevel, IntPtr lpBuffer, uint cbBufSize, out uint pcbBytesNeeded);
/// <summary>
/// 获取服务进程编码
/// </summary>
/// <param name="sc"></param>
/// <returns></returns>
public static int GetServiceProcessId(ServiceController sc)
{
if (sc == null)
throw new ArgumentNullException("sc");
IntPtr zero = IntPtr.Zero;
try
{
UInt32 dwBytesNeeded;
// Call once to figure the size of the output buffer.
QueryServiceStatusEx(sc.ServiceHandle, SC_STATUS_PROCESS_INFO, zero, 0, out dwBytesNeeded);
if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
{
// Allocate required buffer and call again.
zero = Marshal.AllocHGlobal((int)dwBytesNeeded);
if (QueryServiceStatusEx(sc.ServiceHandle, SC_STATUS_PROCESS_INFO, zero, dwBytesNeeded, out dwBytesNeeded))
{
var ssp = new SERVICE_STATUS_PROCESS();
Marshal.PtrToStructure(zero, ssp);
return (int)ssp.dwProcessId;
}
}
}
finally
{
if (zero != IntPtr.Zero)
{
Marshal.FreeHGlobal(zero);
}
}
return -1;
}
/// <summary>
/// 停止服务
/// </summary>
/// <param name="serviceName">服务名称</param>
private void StopService(string serviceName)
{
try
{
var services = ServiceController.GetServices();
var service = services.FirstOrDefault(s => s.ServiceName == serviceName);
if (service != null && service.Status != ServiceControllerStatus.Stopped)
{
var pid = GetServiceProcessId(service);
var myproc = Process.GetProcessById(pid);
myproc.Kill();
service.Close();
service.Dispose();
}
}
catch (Exception e)
{
Logger.Instance.Error($"停止服务:{serviceName}出现错误。", e);
throw new Exception($"停止服务:{serviceName}出现错误,请联系管理员。");
}
}
原文地址:https://www.cnblogs.com/sixi/p/11818988.html
时间: 2024-11-10 16:24:56