157 lines
6.3 KiB
C#
157 lines
6.3 KiB
C#
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Calculator.UIAutomationLibrary
|
|
{
|
|
public class ServiceHelper
|
|
{
|
|
public static void Start(string serviceName, int timeoutInMilliSeconds = 30000)
|
|
{
|
|
IntPtr hService = IntPtr.Zero;
|
|
IntPtr hSCManager = IntPtr.Zero;
|
|
try
|
|
{
|
|
hSCManager = NativeMethods.OpenSCManager(null, null, NativeMethods.SC_MANAGER_ALL_ACCESS);
|
|
if (IntPtr.Zero == hSCManager)
|
|
{
|
|
throw new Exception($"Start: Cannot Open OpenSCManager, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
|
|
hService = NativeMethods.OpenService(hSCManager, serviceName, NativeMethods.SERVICE_ALL_ACCESS);
|
|
if (IntPtr.Zero == hService)
|
|
{
|
|
throw new Exception($"Start: Cannot Open Service, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
|
|
NativeMethods.SERVICE_STATUS serviceStatus = new NativeMethods.SERVICE_STATUS();
|
|
if (!NativeMethods.QueryServiceStatus(hService, ref serviceStatus))
|
|
{
|
|
throw new Exception($"Start: Unable to query status of Service, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
|
|
if (serviceStatus.dwCurrentState != (int)NativeMethods.SERVICE_STATE.SERVICE_RUNNING &&
|
|
serviceStatus.dwCurrentState != (int)NativeMethods.SERVICE_STATE.SERVICE_START_PENDING)
|
|
{
|
|
if (!NativeMethods.StartService(hService, 0, null))
|
|
{
|
|
throw new Exception($"Start: Service cannot be started, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
}
|
|
|
|
WaitForStatus(hService, NativeMethods.SERVICE_STATE.SERVICE_RUNNING, TimeSpan.FromMilliseconds(timeoutInMilliSeconds));
|
|
}
|
|
finally
|
|
{
|
|
if (IntPtr.Zero != hService)
|
|
{
|
|
NativeMethods.CloseServiceHandle(hService);
|
|
}
|
|
if (IntPtr.Zero != hSCManager)
|
|
{
|
|
NativeMethods.CloseServiceHandle(hSCManager);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Stop(string serviceName, int timeoutInMilliSeconds = 30000)
|
|
{
|
|
IntPtr hSCManager = IntPtr.Zero;
|
|
IntPtr hService = IntPtr.Zero;
|
|
try
|
|
{
|
|
hSCManager = NativeMethods.OpenSCManager(null, null, NativeMethods.SC_MANAGER_ALL_ACCESS);
|
|
if (IntPtr.Zero == hSCManager)
|
|
{
|
|
throw new Exception($"Stop: Cannot Open OpenSCManager, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
|
|
hService = NativeMethods.OpenService(hSCManager, serviceName, NativeMethods.SERVICE_ALL_ACCESS);
|
|
if (IntPtr.Zero == hService)
|
|
{
|
|
throw new Exception($"Stop: Cannot Open Service, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
|
|
NativeMethods.SERVICE_STATUS serviceStatus = new NativeMethods.SERVICE_STATUS();
|
|
if (!NativeMethods.QueryServiceStatus(hService, ref serviceStatus))
|
|
{
|
|
throw new Exception($"Stop: Unable to query status of Service, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
|
|
if (serviceStatus.dwCurrentState != (int)NativeMethods.SERVICE_STATE.SERVICE_STOPPED &&
|
|
serviceStatus.dwCurrentState != (int)NativeMethods.SERVICE_STATE.SERVICE_STOP_PENDING)
|
|
{
|
|
if (!NativeMethods.ControlService(hService, NativeMethods.SERVICE_CONTROL.STOP, ref serviceStatus))
|
|
{
|
|
throw new Exception($"Stop: Service cannot be stopped, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
}
|
|
|
|
WaitForStatus(hService, NativeMethods.SERVICE_STATE.SERVICE_STOPPED, TimeSpan.FromMilliseconds(timeoutInMilliSeconds));
|
|
}
|
|
finally
|
|
{
|
|
if (IntPtr.Zero != hService)
|
|
{
|
|
NativeMethods.CloseServiceHandle(hService);
|
|
}
|
|
|
|
if (IntPtr.Zero != hSCManager)
|
|
{
|
|
NativeMethods.CloseServiceHandle(hSCManager);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool IsInstalled(string svcName)
|
|
{
|
|
IntPtr sc_handle = NativeMethods.OpenSCManager(null, null, NativeMethods.SC_MANAGER_ALL_ACCESS);
|
|
if (sc_handle == IntPtr.Zero)
|
|
{
|
|
throw new Exception($"IsInstalled: Cannot open service manager, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
|
|
bool bResult = false;
|
|
IntPtr sv_handle = NativeMethods.OpenService(sc_handle, svcName, NativeMethods.SERVICE_QUERY_CONFIG);
|
|
if (sv_handle.ToInt64() != 0)
|
|
{
|
|
bResult = true;
|
|
NativeMethods.CloseServiceHandle(sv_handle);
|
|
}
|
|
NativeMethods.CloseServiceHandle(sc_handle);
|
|
return bResult;
|
|
}
|
|
|
|
private static void WaitForStatus(IntPtr hService, NativeMethods.SERVICE_STATE desiredStatus, TimeSpan timeout)
|
|
{
|
|
Stopwatch swLoop = new Stopwatch();
|
|
swLoop.Start();
|
|
|
|
NativeMethods.SERVICE_STATUS serviceStatus = new NativeMethods.SERVICE_STATUS();
|
|
|
|
do
|
|
{
|
|
Thread.Sleep(500);
|
|
if (!NativeMethods.QueryServiceStatus(hService, ref serviceStatus))
|
|
{
|
|
throw new Exception($"WaitForStatus: Unable to query status of service, {Marshal.GetLastWin32Error()}");
|
|
}
|
|
}
|
|
while (serviceStatus.dwCurrentState != (int)desiredStatus && (swLoop.ElapsedMilliseconds <= timeout.TotalMilliseconds));
|
|
|
|
if (serviceStatus.dwCurrentState != (int)desiredStatus)
|
|
{
|
|
throw new Exception($"WaitForStatus: Service failed to reach desired state: {desiredStatus}, current state: {serviceStatus.dwCurrentState}");
|
|
}
|
|
}
|
|
}
|
|
}
|