/// <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);
        }
Exemplo n.º 2
0
        /// <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);
        }