/// <summary> /// Queries the status and other configuration properties of a service. /// </summary> /// <param name="serviceName">The internal service name. Ex:"Print Spooler" is "Spooler".</param> /// <param name="machineName">The server on which the service is running.</param> /// <returns>The service configuration details.</returns> public static ServiceConfig QueryStatus(string serviceName, string machineName) { ServiceConfig config = new ServiceConfig() { ServiceName = serviceName, ServerName = machineName }; ManagementObjectCollection services = GetServicesByServiceName(serviceName, machineName); foreach (ManagementObject service in services) { config.State = service.GetPropertyValue("State").ToString(); config.AcceptStop = bool.Parse(service.GetPropertyValue("AcceptStop").ToString()); config.DisplayName = service.GetPropertyValue("DisplayName").ToString(); config.LogOnAs = service.GetPropertyValue("StartName").ToString(); config.PathName = service.GetPropertyValue("PathName").ToString(); config.ProcessId = int.Parse(service.GetPropertyValue("ProcessId").ToString()); string startMode = service.GetPropertyValue("StartMode").ToString(); if (startMode == "Auto") { startMode = "Automatic"; } config.StartMode = (ServiceStartMode)Enum.Parse(typeof(ServiceStartMode), startMode); } try { ServiceUtilWin32Helper svcUtil = new ServiceUtilWin32Helper(machineName); config.Description = svcUtil.GetServiceDescription(serviceName); } catch { } //eat the error return(config); }
/// <summary> /// Executes the main workflow. /// </summary> public void ExecuteAction(HandlerStartInfo startInfo) { string context = "ExecuteAction"; _startInfo = startInfo; string msg = Utils.GetHeaderMessage(string.Format("Entering Main Workflow.")); if (OnStepStarting(context, msg)) { return; } OnStepProgress("ExecuteAction", Utils.CompressXml(startInfo.Parameters)); Stopwatch clock = new Stopwatch(); clock.Start(); IProcessState state = new ServiceConfig(); Exception ex = null; try { if (ValidateParameters()) { switch (_wfp.TargetType) { case ServiceType.Service: { state = ManageService(startInfo.IsDryRun); break; } case ServiceType.AppPool: { state = ManageAppPool(startInfo.IsDryRun); break; } case ServiceType.ScheduledTask: { state = ManageScheduledTask(startInfo.IsDryRun); break; } } } else { throw new Exception("Could not validate parameters."); } } catch (Exception exception) { ex = exception; } if (_wfp.IsValid) { OnStepProgress(context, "\r\n\r\n" + state.ToXml(true) + "\r\n"); } bool ok = ex == null; OnProgress(context, state.State, ok ? StatusType.Complete : StatusType.Failed, _startInfo.InstanceId, int.MaxValue, false, ex); }
/// <summary> /// Stops a Windows service. /// </summary> /// <param name="serviceName">The internal service name. Ex:"Print Spooler" is "Spooler".</param> /// <param name="machineName">The server on which the service is running.</param> /// <param name="millisecondsTimeout">Timeout until PId kill. Negative value will issue immediate kill, 0 will wait infinitely, positive value equals milliseconds to wait.</param> /// <param name="desiredStartMode">Sets the StartMode of the service.</param> /// <returns>True if status == Stopped, otherwise false.</returns> public static bool Stop(string serviceName, string machineName, int millisecondsTimeout, ServiceStartMode desiredStartMode = ServiceStartMode.Unchanged) { ServiceController sc = new ServiceController(serviceName, machineName); ServiceConfig svc = QueryStatus(serviceName, machineName); Stopwatch waitTimeElapsed = new Stopwatch(); if (millisecondsTimeout < 0) { KillProcesses(svc.ProcessId, machineName); } else { if (sc.CanStop) { sc.Stop(); if (millisecondsTimeout > 0) { try { waitTimeElapsed.Start(); sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMilliseconds(millisecondsTimeout)); waitTimeElapsed.Stop(); } catch (Exception) { waitTimeElapsed.Stop(); KillProcesses(svc.ProcessId, machineName); } } else { sc.WaitForStatus(ServiceControllerStatus.Stopped); } } } //if the PId is still around, run out the clock and kill it. string processName = System.IO.Path.GetFileName(svc.PathName.Replace("\"", string.Empty)); int pid = GetProcessesByProcessNamePId(processName, svc.ProcessId, machineName); long waitTimeRemaining = (long)millisecondsTimeout - waitTimeElapsed.ElapsedMilliseconds; if (pid != 0) { if (waitTimeRemaining > 0) { System.Threading.Thread.Sleep((int)waitTimeRemaining); } pid = GetProcessesByProcessNamePId(processName, svc.ProcessId, machineName); if (pid != 0) { KillProcesses(svc.ProcessId, machineName); } } if (desiredStartMode != ServiceStartMode.Unchanged) { ChangeStartMode(sc.ServiceName, machineName, desiredStartMode); } return(sc.Status == ServiceControllerStatus.Stopped); }