initial checkin of yaulw (locally)
This commit is contained in:
212
Process/ServiceW.cs
Normal file
212
Process/ServiceW.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.ServiceProcess;
|
||||
using Yaulw.Win32;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Yaulw.Process
|
||||
{
|
||||
/// <remarks>
|
||||
/// Wrapper Class around System.ServiceProcess's ServiceControl Class,
|
||||
/// ~Little helper functions to make sure that we can safely interact with Services
|
||||
/// </remarks>
|
||||
public static class ServiceW
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks to see if the service exists on the local computer
|
||||
/// </summary>
|
||||
/// <param name="ServiceName">Name of Service to Check</param>
|
||||
/// <returns>true if it exists, false otherwise</returns>
|
||||
public static bool DoesServiceExist(string ServiceName)
|
||||
{
|
||||
try
|
||||
{
|
||||
ServiceController scm = new ServiceController(ServiceName);
|
||||
if (scm != null && !String.IsNullOrEmpty(scm.ServiceName))
|
||||
{
|
||||
scm.Dispose();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick check to see if the service is running
|
||||
/// </summary>
|
||||
/// <param name="ServiceName">Name of Service to Check</param>
|
||||
/// <returns>true if the service is running, false otherwise, if it doesn't exist returns true</returns>
|
||||
public static bool IsServiceRunning(string ServiceName)
|
||||
{
|
||||
ServiceController scm = null;
|
||||
try
|
||||
{
|
||||
scm = new ServiceController(ServiceName);
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
|
||||
if (scm != null)
|
||||
{
|
||||
bool bIsRunning = (scm.Status == ServiceControllerStatus.Running);
|
||||
scm.Dispose();
|
||||
return bIsRunning;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to Restart the Service
|
||||
/// </summary>
|
||||
/// <param name="ServiceName">Name of Service to Check</param>
|
||||
/// <param name="bKillServiceByForceIfNeedBe">Set to true to try to force a Service Close by killing the Process, if the service is hanging</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Number of Seconds to wait for Service To Close/Start</param>
|
||||
/// <param name="nStartupDelayInSeconds">Number of Seconds to wait inbetween closing and starting</param>
|
||||
/// <returns>true if successful, false otherwise</returns>
|
||||
public static bool RestartService(string ServiceName, bool bKillServiceByForceIfNeedBe = true, int WaitTimeoutInSeconds = 240, int nStartupDelayInSeconds = 2)
|
||||
{
|
||||
// Stop the Service
|
||||
if (!StopService(ServiceName, bKillServiceByForceIfNeedBe, WaitTimeoutInSeconds))
|
||||
return false;
|
||||
|
||||
// Delay Starting the Services for 'n' seconds
|
||||
if (nStartupDelayInSeconds > 0)
|
||||
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(nStartupDelayInSeconds));
|
||||
|
||||
// Start the Service
|
||||
bool bIsStarted = StartService(ServiceName, WaitTimeoutInSeconds);
|
||||
return bIsStarted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to start a service
|
||||
/// </summary>
|
||||
/// <param name="ServiceName">Name of Service to Check</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Number of seconds to wait for Service to Start</param>
|
||||
/// <returns>true if successful, false otherwise</returns>
|
||||
public static bool StartService(string ServiceName, int WaitTimeoutInSeconds = 240)
|
||||
{
|
||||
ServiceController scm = null;
|
||||
try
|
||||
{
|
||||
scm = new ServiceController(ServiceName);
|
||||
|
||||
// Wait for 'Stopped' State
|
||||
if (scm.Status != ServiceControllerStatus.Running)
|
||||
{
|
||||
scm.Start();
|
||||
if (WaitTimeoutInSeconds > 0)
|
||||
scm.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(WaitTimeoutInSeconds));
|
||||
}
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
|
||||
if (scm != null)
|
||||
{
|
||||
bool bSuccess = (scm.Status == ServiceControllerStatus.Running);
|
||||
scm.Dispose();
|
||||
return bSuccess;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to stop a service
|
||||
/// </summary>
|
||||
/// <param name="ServiceName">Name of Service to Check</param>
|
||||
/// <param name="bKillServiceByForceIfNeedBe">Set to true to try to force a Service Close by killing the Process, if the service is hanging</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Number of seconds to wait for Service to Stop</param>
|
||||
/// <returns>true if successful, false otherwise</returns>
|
||||
public static bool StopService(string ServiceName, bool bKillServiceByForceIfNeedBe = true, int WaitTimeoutInSeconds = 240)
|
||||
{
|
||||
ServiceController scm = null;
|
||||
try
|
||||
{
|
||||
scm = new ServiceController(ServiceName);
|
||||
|
||||
// Wait for 'Stopped' State
|
||||
if (scm.Status != ServiceControllerStatus.Stopped)
|
||||
{
|
||||
scm.Stop();
|
||||
if (WaitTimeoutInSeconds > 0)
|
||||
scm.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(WaitTimeoutInSeconds));
|
||||
}
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
|
||||
try
|
||||
{
|
||||
if (scm != null)
|
||||
{
|
||||
bool bSuccess = (scm.Status == ServiceControllerStatus.Stopped);
|
||||
|
||||
// Always try Killing Service By Force, even if bSuccess is true,
|
||||
// just to try to guarantee that the service is dead for good
|
||||
if (bKillServiceByForceIfNeedBe)
|
||||
bSuccess = StopServiceByForce(scm) || bSuccess;
|
||||
|
||||
scm.Dispose();
|
||||
return bSuccess;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Brutal way to stop a service * Not Recommended *,
|
||||
/// according to article:
|
||||
/// </summary>
|
||||
/// <see cref="http://community.bartdesmet.net/blogs/bart/archive/2004/10/16/438.aspx"/>
|
||||
/// <see cref="http://stackoverflow.com/questions/884853/service-not-fully-stopped-after-servicecontroller-stop"/>
|
||||
/// <param name="scm">a Service Controller Object whose PID you would like to kill</param>
|
||||
/// <returns>true if successfull, false otherwise</returns>
|
||||
private static bool StopServiceByForce(ServiceController scm)
|
||||
{
|
||||
Structures.SERVICE_STATUS_PROCESS ssp = new Structures.SERVICE_STATUS_PROCESS();
|
||||
int ignored;
|
||||
|
||||
try
|
||||
{
|
||||
// Obtain information about the service, and specifically its hosting process,
|
||||
// from the Service Control Manager.
|
||||
if (!Advapi32.QueryServiceStatusEx(scm.ServiceHandle.DangerousGetHandle(), Definitions.SC_STATUS_PROCESS_INFO, ref ssp, Marshal.SizeOf(ssp), out ignored))
|
||||
{
|
||||
//throw new Exception("Couldn't obtain service process information.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// A few quick sanity checks that what the caller wants is *possible*.
|
||||
if (ssp.dwServiceType != Definitions.SERVICE_WIN32_OWN_PROCESS)
|
||||
{
|
||||
//throw new Exception("Can't wait for the service's hosting process to exit because there may be multiple services in the process (dwServiceType is not SERVICE_WIN32_OWN_PROCESS");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((ssp.dwServiceFlags & Definitions.SERVICE_RUNS_IN_SYSTEM_PROCESS) != 0)
|
||||
{
|
||||
//throw new Exception("Can't wait for the service's hosting process to exit because the hosting process is a critical system process that will not exit (SERVICE_RUNS_IN_SYSTEM_PROCESS flag set)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ssp.dwProcessId == 0)
|
||||
{
|
||||
//throw new Exception("Can't wait for the service's hosting process to exit because the process ID is not known.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try closing the Process Manually
|
||||
bool bCloseSuccess = PStarter.KillProcess((uint)ssp.dwProcessId, false, 1, false, 2);
|
||||
return bCloseSuccess;
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user