Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
Service.cs2947 linesDownload Raw Back to management
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#if !UNIX // Not built on Unix5 6using System;7using System.Collections.Generic;8using System.ComponentModel; // Win32Exception9using System.Diagnostics.CodeAnalysis;10using System.Management.Automation;11using System.Management.Automation.Internal;12using System.Runtime.InteropServices; // Marshal, DllImport13using System.Runtime.Serialization;14using System.Security.AccessControl;15using System.ServiceProcess;16using Dbg = System.Management.Automation.Diagnostics;17using DWORD = System.UInt32;18using NakedWin32Handle = System.IntPtr;19 20namespace Microsoft.PowerShell.Commands21{22    #region ServiceBaseCommand23 24    /// <summary>25    /// This class implements the base for service commands.26    /// </summary>27    public abstract class ServiceBaseCommand : Cmdlet28    {29        #region Internal30 31        /// <summary>32        /// Confirm that the operation should proceed.33        /// </summary>34        /// <param name="service">Service object to be acted on.</param>35        /// <returns>True if operation should continue, false otherwise.</returns>36        protected bool ShouldProcessServiceOperation(ServiceController service)37        {38            return ShouldProcessServiceOperation(39                service.DisplayName,40                service.ServiceName);41        }42 43        /// <summary>44        /// Confirm that the operation should proceed.45        /// </summary>46        /// <param name="displayName">Display name of service to be acted on.</param>47        /// <param name="serviceName">Service name of service to be acted on.</param>48        /// <returns>True if operation should continue, false otherwise.</returns>49        protected bool ShouldProcessServiceOperation(50            string displayName, string serviceName)51        {52            string name = StringUtil.Format(ServiceResources.ServiceNameForConfirmation,53                displayName,54                serviceName);55 56            return ShouldProcess(name);57        }58 59        /// <summary>60        /// Writes a non-terminating error.61        /// </summary>62        /// <param name="service"></param>63        /// <param name="innerException"></param>64        /// <param name="errorId"></param>65        /// <param name="errorMessage"></param>66        /// <param name="category"></param>67        internal void WriteNonTerminatingError(68            ServiceController service,69            Exception innerException,70            string errorId,71            string errorMessage,72            ErrorCategory category)73        {74            WriteNonTerminatingError(75                service.ServiceName,76                service.DisplayName,77                service,78                innerException,79                errorId,80                errorMessage,81                category);82        }83 84        /// <summary>85        /// Writes a non-terminating error.86        /// </summary>87        /// <param name="serviceName"></param>88        /// <param name="displayName"></param>89        /// <param name="targetObject"></param>90        /// <param name="innerException"></param>91        /// <param name="errorId"></param>92        /// <param name="errorMessage"></param>93        /// <param name="category"></param>94        internal void WriteNonTerminatingError(95            string serviceName,96            string displayName,97            object targetObject,98            Exception innerException,99            string errorId,100            string errorMessage,101            ErrorCategory category)102        {103            string message = StringUtil.Format(errorMessage,104                serviceName,105                displayName,106                (innerException == null) ? category.ToString() : innerException.Message);107 108            var exception = new ServiceCommandException(message, innerException);109            exception.ServiceName = serviceName;110 111            WriteError(new ErrorRecord(exception, errorId, category, targetObject));112        }113 114        internal void SetServiceSecurityDescriptor(115            ServiceController service,116            string securityDescriptorSddl,117            NakedWin32Handle hService)118        {119            var rawSecurityDescriptor = new RawSecurityDescriptor(securityDescriptorSddl);120            RawAcl rawDiscretionaryAcl = rawSecurityDescriptor.DiscretionaryAcl;121            var discretionaryAcl = new DiscretionaryAcl(false, false, rawDiscretionaryAcl);122 123            byte[] rawDacl = new byte[discretionaryAcl.BinaryLength];124            discretionaryAcl.GetBinaryForm(rawDacl, 0);125            rawSecurityDescriptor.DiscretionaryAcl = new RawAcl(rawDacl, 0);126            byte[] securityDescriptorByte = new byte[rawSecurityDescriptor.BinaryLength];127            rawSecurityDescriptor.GetBinaryForm(securityDescriptorByte, 0);128 129            bool status = NativeMethods.SetServiceObjectSecurity(130                hService,131                SecurityInfos.DiscretionaryAcl,132                securityDescriptorByte);133 134            if (!status)135            {136                int lastError = Marshal.GetLastWin32Error();137                Win32Exception exception = new(lastError);138                bool accessDenied = exception.NativeErrorCode == NativeMethods.ERROR_ACCESS_DENIED;139                WriteNonTerminatingError(140                    service,141                    exception,142                    nameof(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl),143                    StringUtil.Format(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl, service.ServiceName, exception.Message),144                    accessDenied ? ErrorCategory.PermissionDenied : ErrorCategory.InvalidOperation);145            }146        }147        #endregion Internal148    }149    #endregion ServiceBaseCommand150 151    #region MultipleServiceCommandBase152 153    /// <summary>154    /// This class implements the base for service commands which can155    /// operate on multiple services.156    /// </summary>157    public abstract class MultipleServiceCommandBase : ServiceBaseCommand158    {159        #region Parameters160 161        /// <summary>162        /// The various process selection modes.163        /// </summary>164        internal enum SelectionMode165        {166            /// <summary>167            /// Select all services.168            /// </summary>169            Default = 0,170            /// <summary>171            /// Select services matching the supplied names.172            /// </summary>173            DisplayName = 1,174            /// <summary>175            /// Select services based on pipeline input.176            /// </summary>177            InputObject = 2,178            /// <summary>179            /// Select services by Service name.180            /// </summary>181            ServiceName = 3182        }183        /// <summary>184        /// Holds the selection mode setting.185        /// </summary>186        internal SelectionMode selectionMode;187 188        /// <remarks>189        /// The ServiceName parameter is declared in subclasses,190        /// since it is optional for GetService and mandatory otherwise.191        /// </remarks>192        internal string[] serviceNames = null;193 194        /// <summary>195        /// Gets/sets an array of display names for services.196        /// </summary>197        [Parameter(ParameterSetName = "DisplayName", Mandatory = true)]198        public string[] DisplayName199        {200            get201            {202                return displayNames;203            }204 205            set206            {207                displayNames = value;208                selectionMode = SelectionMode.DisplayName;209            }210        }211 212        internal string[] displayNames = null;213 214        /// <summary>215        /// Lets you include particular services.  Services not matching216        /// one of these (if specified) are excluded.217        /// These are interpreted as either ServiceNames or DisplayNames218        /// according to the parameter set.219        /// </summary>220        [Parameter]221        [ValidateNotNullOrEmpty]222        public string[] Include223        {224            get225            {226                return include;227            }228 229            set230            {231                include = value;232            }233        }234 235        internal string[] include = null;236 237        /// <summary>238        /// Lets you exclude particular services.  Services matching239        /// one of these (if specified) are excluded.240        /// These are interpreted as either ServiceNames or DisplayNames241        /// according to the parameter set.242        /// </summary>243        [Parameter]244        [ValidateNotNullOrEmpty]245        public string[] Exclude246        {247            get248            {249                return exclude;250            }251 252            set253            {254                exclude = value;255            }256        }257 258        internal string[] exclude = null;259 260        // 1054295-2004/12/01-JonN This also works around 1054295.261        /// <summary>262        /// If the input is a stream of [collections of]263        /// ServiceController objects, we bypass the ServiceName and264        /// DisplayName parameters and read the ServiceControllers265        /// directly.  This allows us to deal with services which266        /// have wildcard characters in their name (servicename or267        /// displayname).268        /// </summary>269        /// <value>ServiceController objects</value>270        [Parameter(ParameterSetName = "InputObject", ValueFromPipeline = true)]271        [ValidateNotNullOrEmpty]272        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]273        public ServiceController[] InputObject274        {275            get276            {277                return _inputObject;278            }279 280            set281            {282                _inputObject = value;283                selectionMode = SelectionMode.InputObject;284            }285        }286 287        private ServiceController[] _inputObject = null;288        #endregion Parameters289 290        #region Internal291 292        /// <summary>293        /// Gets an array of all services.294        /// </summary>295        /// <value>296        /// An array of <see cref="ServiceController"/> components that represents all the service resources.297        /// </value>298        /// <exception cref="System.Security.SecurityException">299        /// MSDN does not document the list of exceptions,300        /// but it is reasonable to expect that SecurityException is301        /// among them.  Errors here will terminate the cmdlet.302        /// </exception>303        internal ServiceController[] AllServices => _allServices ??= ServiceController.GetServices();304 305        private ServiceController[] _allServices;306 307        internal ServiceController GetOneService(string nameOfService)308        {309            Dbg.Assert(!WildcardPattern.ContainsWildcardCharacters(nameOfService), "Caller should verify that nameOfService doesn't contain wildcard characters");310 311            try312            {313                var sc = new ServiceController(nameOfService);314                // This will throw if the service doesn't exist315                var unused = sc.Status;316 317                // No exception, then this is an existing, valid service. Return it.318                return sc;319            }320            catch (InvalidOperationException) { }321            catch (ArgumentException) { }322 323            return null;324        }325 326        /// <summary>327        /// Retrieve the list of all services matching the ServiceName,328        /// DisplayName, Include and Exclude parameters, sorted by ServiceName.329        /// </summary>330        /// <returns></returns>331        internal List<ServiceController> MatchingServices()332        {333            List<ServiceController> matchingServices;334            switch (selectionMode)335            {336                case SelectionMode.DisplayName:337                    matchingServices = MatchingServicesByDisplayName();338                    break;339                case SelectionMode.InputObject:340                    matchingServices = MatchingServicesByInput();341                    break;342                default:343                    matchingServices = MatchingServicesByServiceName();344                    break;345            }346            // 2004/12/16 Note that the services will be sorted347            //  before being stopped.  JimTru confirms that this is OK.348            matchingServices.Sort(ServiceComparison);349            return matchingServices;350        }351 352        // sort by servicename353        private static int ServiceComparison(ServiceController x, ServiceController y)354        {355            return string.Compare(x.ServiceName, y.ServiceName, StringComparison.OrdinalIgnoreCase);356        }357 358        /// <summary>359        /// Retrieves the list of all services matching the ServiceName,360        /// Include and Exclude parameters.361        /// Generates a non-terminating error for each specified362        /// service name which is not found even though it contains363        /// no wildcards.364        /// </summary>365        /// <returns></returns>366        /// <remarks>367        /// We do not use the ServiceController(string serviceName)368        /// constructor variant, since the resultant369        /// ServiceController.ServiceName is the provided serviceName370        /// even when that differs from the real ServiceName by case.371        /// </remarks>372        private List<ServiceController> MatchingServicesByServiceName()373        {374            List<ServiceController> matchingServices = new();375 376            if (serviceNames == null)377            {378                foreach (ServiceController service in AllServices)379                {380                    IncludeExcludeAdd(matchingServices, service, false);381                }382 383                return matchingServices;384            }385 386            foreach (string pattern in serviceNames)387            {388                bool found = false;389 390                if (WildcardPattern.ContainsWildcardCharacters(pattern))391                {392                    WildcardPattern wildcard = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase);393                    foreach (ServiceController service in AllServices)394                    {395                        if (!wildcard.IsMatch(service.ServiceName))396                            continue;397                        found = true;398                        IncludeExcludeAdd(matchingServices, service, true);399                    }400                }401                else402                {403                    ServiceController service = GetOneService(pattern);404                    if (service != null)405                    {406                        found = true;407                        IncludeExcludeAdd(matchingServices, service, true);408                    }409                }410 411                if (!found && !WildcardPattern.ContainsWildcardCharacters(pattern))412                {413                    WriteNonTerminatingError(414                        pattern,415                        string.Empty,416                        pattern,417                        null,418                        "NoServiceFoundForGivenName",419                        ServiceResources.NoServiceFoundForGivenName,420                        ErrorCategory.ObjectNotFound);421                }422            }423 424            return matchingServices;425        }426 427        /// <summary>428        /// Retrieves the list of all services matching the DisplayName,429        /// Include and Exclude parameters.430        /// Generates a non-terminating error for each specified431        /// display name which is not found even though it contains432        /// no wildcards.433        /// </summary>434        /// <returns></returns>435        private List<ServiceController> MatchingServicesByDisplayName()436        {437            List<ServiceController> matchingServices = new();438            if (DisplayName == null)439            {440                Diagnostics.Assert(false, "null DisplayName");441                throw PSTraceSource.NewInvalidOperationException();442            }443 444            foreach (string pattern in DisplayName)445            {446                WildcardPattern wildcard =447                    WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase);448                bool found = false;449                foreach (ServiceController service in AllServices)450                {451                    if (!wildcard.IsMatch(service.DisplayName))452                        continue;453                    found = true;454                    IncludeExcludeAdd(matchingServices, service, true);455                }456 457                if (!found && !WildcardPattern.ContainsWildcardCharacters(pattern))458                {459                    WriteNonTerminatingError(460                        string.Empty,461                        pattern,462                        pattern,463                        null,464                        "NoServiceFoundForGivenDisplayName",465                        ServiceResources.NoServiceFoundForGivenDisplayName,466                        ErrorCategory.ObjectNotFound);467                }468            }469 470            return matchingServices;471        }472 473        /// <summary>474        /// Retrieves the list of all services matching the InputObject,475        /// Include and Exclude parameters.476        /// </summary>477        /// <returns></returns>478        private List<ServiceController> MatchingServicesByInput()479        {480            List<ServiceController> matchingServices = new();481            if (InputObject == null)482            {483                Diagnostics.Assert(false, "null InputObject");484                throw PSTraceSource.NewInvalidOperationException();485            }486 487            foreach (ServiceController service in InputObject)488            {489                service.Refresh();490                IncludeExcludeAdd(matchingServices, service, false);491            }492 493            return matchingServices;494        }495 496        /// <summary>497        /// Add <paramref name="service"/> to <paramref name="list"/>,498        /// but only if it passes the Include and Exclude filters (if present)499        /// and (if <paramref name="checkDuplicates"/>) if it is not500        /// already on  <paramref name="list"/>.501        /// </summary>502        /// <param name="list">List of services.</param>503        /// <param name="service">Service to add to list.</param>504        /// <param name="checkDuplicates">Check list for duplicates.</param>505        private void IncludeExcludeAdd(506            List<ServiceController> list,507            ServiceController service,508            bool checkDuplicates)509        {510            if (include != null && !Matches(service, include))511                return;512            if (exclude != null && Matches(service, exclude))513                return;514            if (checkDuplicates)515            {516                foreach (ServiceController sc in list)517                {518                    if (sc.ServiceName == service.ServiceName &&519                        sc.MachineName == service.MachineName)520                    {521                        return;522                    }523                }524            }525 526            list.Add(service);527        }528 529        /// <summary>530        /// Check whether <paramref name="service"/> matches the list of531        /// patterns in <paramref name="matchList"/>.532        /// </summary>533        /// <param name="service"></param>534        /// <param name="matchList"></param>535        /// <returns></returns>536        private bool Matches(ServiceController service, string[] matchList)537        {538            if (matchList == null)539                throw PSTraceSource.NewArgumentNullException(nameof(matchList));540            string serviceID = (selectionMode == SelectionMode.DisplayName)541                                ? service.DisplayName542                                : service.ServiceName;543            foreach (string pattern in matchList)544            {545                WildcardPattern wildcard = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase);546                if (wildcard.IsMatch(serviceID))547                    return true;548            }549 550            return false;551        }552        #endregion Internal553 554    }555    #endregion MultipleServiceCommandBase556 557    #region GetServiceCommand558    /// <summary>559    /// This class implements the get-service command.560    /// </summary>561    [Cmdlet(VerbsCommon.Get, "Service", DefaultParameterSetName = "Default",562        HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096496", RemotingCapability = RemotingCapability.SupportedByCommand)]563    [OutputType(typeof(ServiceController))]564    public sealed class GetServiceCommand : MultipleServiceCommandBase565    {566        #region Parameters567        /// <summary>568        /// Gets/sets an array of service names.569        /// </summary>570        /// <remarks>571        /// The ServiceName parameter is declared in subclasses,572        /// since it is optional for GetService and mandatory otherwise.573        /// </remarks>574        [Parameter(Position = 0, ParameterSetName = "Default", ValueFromPipelineByPropertyName = true, ValueFromPipeline = true)]575        [ValidateNotNullOrEmpty()]576        [Alias("ServiceName")]577        public string[] Name578        {579            get580            {581                return serviceNames;582            }583 584            set585            {586                serviceNames = value;587                selectionMode = SelectionMode.ServiceName;588            }589        }590 591        /// <summary>592        /// This returns the DependentServices of the specified service.593        /// </summary>594        [Parameter]595        [Alias("DS")]596        public SwitchParameter DependentServices { get; set; }597 598        /// <summary>599        /// This returns the ServicesDependedOn of the specified service.600        /// </summary>601        [Parameter]602        [Alias("SDO", "ServicesDependedOn")]603        public SwitchParameter RequiredServices { get; set; }604 605        #endregion Parameters606 607        #region Overrides608        /// <summary>609        /// Write the service objects.610        /// </summary>611        protected override void ProcessRecord()612        {613            nint scManagerHandle = nint.Zero;614            if (!DependentServices && !RequiredServices)615            {616                // As Get-Service only works on local services we get this once617                // to retrieve extra properties added by PowerShell.618                scManagerHandle = NativeMethods.OpenSCManagerW(619                    lpMachineName: null,620                    lpDatabaseName: null,621                    dwDesiredAccess: NativeMethods.SC_MANAGER_CONNECT);622                if (scManagerHandle == nint.Zero)623                {624                    Win32Exception exception = new();625                    string message = StringUtil.Format(ServiceResources.FailToOpenServiceControlManager, exception.Message);626                    ServiceCommandException serviceException = new ServiceCommandException(message, exception);627                    ErrorRecord err = new ErrorRecord(628                        serviceException,629                        "FailToOpenServiceControlManager",630                        ErrorCategory.PermissionDenied,631                        null);632                    ThrowTerminatingError(err);633                }634            }635 636            try637            {638                foreach (ServiceController service in MatchingServices())639                {640                    if (!DependentServices.IsPresent && !RequiredServices.IsPresent)641                    {642                        WriteObject(AddProperties(scManagerHandle, service));643                    }644                    else645                    {646                        if (DependentServices.IsPresent)647                        {648                            foreach (ServiceController dependantserv in service.DependentServices)649                            {650                                WriteObject(dependantserv);651                            }652                        }653 654                        if (RequiredServices.IsPresent)655                        {656                            foreach (ServiceController servicedependedon in service.ServicesDependedOn)657                            {658                                WriteObject(servicedependedon);659                            }660                        }661                    }662                }663            }664            finally665            {666                if (scManagerHandle != nint.Zero)667                {668                    bool succeeded = NativeMethods.CloseServiceHandle(scManagerHandle);669                    Diagnostics.Assert(succeeded, "SCManager handle close failed");670                }671            }672        }673 674        #endregion Overrides675 676#nullable enable677 678        /// <summary>679        /// Writes a verbose message when a service property query fails.680        /// </summary>681        /// <param name="serviceName">Name of the service.</param>682        /// <param name="propertyName">Name of the property that failed to be queried.</param>683        private void WriteServicePropertyError(string serviceName, string propertyName)684        {685            Win32Exception e = new(Marshal.GetLastWin32Error());686            WriteVerbose(687                StringUtil.Format(688                    ServiceResources.CouldNotGetServiceProperty,689                    serviceName,690                    propertyName,691                    e.Message));692        }693 694        /// <summary>695        /// Adds UserName, Description, BinaryPathName, DelayedAutoStart and StartupType to a ServiceController object.696        /// </summary>697        /// <param name="scManagerHandle">Handle to the local SCManager instance.</param>698        /// <param name="service"></param>699        /// <returns>ServiceController as PSObject with UserName, Description and StartupType added.</returns>700        private PSObject AddProperties(nint scManagerHandle, ServiceController service)701        {702            NakedWin32Handle hService = nint.Zero;703 704            // As these are optional values, a failure due to permissions or705            // other problem is ignored and the properties are set to null.706            bool? isDelayedAutoStart = null;707            string? binPath = null;708            string? description = null;709            string? startName = null;710            ServiceStartupType startupType = ServiceStartupType.InvalidValue;711            try712            {713                // We don't use service.ServiceHandle as that requests714                // SERVICE_ALL_ACCESS when we only need SERVICE_QUERY_CONFIG.715                hService = NativeMethods.OpenServiceW(716                    scManagerHandle,717                    service.ServiceName,718                    NativeMethods.SERVICE_QUERY_CONFIG719                );720                if (hService != nint.Zero)721                {722                    if (NativeMethods.QueryServiceConfig2(723                        hService,724                        NativeMethods.SERVICE_CONFIG_DESCRIPTION,725                        out NativeMethods.SERVICE_DESCRIPTIONW descriptionInfo))726                    {727                        description = descriptionInfo.lpDescription;728                    }729                    else730                    {731                        WriteServicePropertyError(service.ServiceName, nameof(NativeMethods.SERVICE_DESCRIPTIONW));732                    }733 734                    if (NativeMethods.QueryServiceConfig2(735                        hService,736                        NativeMethods.SERVICE_CONFIG_DELAYED_AUTO_START_INFO,737                        out NativeMethods.SERVICE_DELAYED_AUTO_START_INFO autostartInfo))738                    {739                        isDelayedAutoStart = autostartInfo.fDelayedAutostart;740                    }741                    else742                    {743                        WriteServicePropertyError(service.ServiceName, nameof(NativeMethods.SERVICE_DELAYED_AUTO_START_INFO));744                    }745 746                    if (NativeMethods.QueryServiceConfig(747                        hService,748                        out NativeMethods.QUERY_SERVICE_CONFIG serviceInfo))749                    {750                        binPath = serviceInfo.lpBinaryPathName;751                        startName = serviceInfo.lpServiceStartName;752                        if (isDelayedAutoStart.HasValue)753                        {754                            startupType = NativeMethods.GetServiceStartupType(755                                (ServiceStartMode)serviceInfo.dwStartType,756                                isDelayedAutoStart.Value);757                        }758                    }759                    else760                    {761                        WriteServicePropertyError(service.ServiceName, nameof(NativeMethods.QUERY_SERVICE_CONFIG));762                    }763                }764                else765                {766                    // handle when OpenServiceW itself fails:767                    WriteServicePropertyError(service.ServiceName, nameof(NativeMethods.SERVICE_QUERY_CONFIG));768                }769            }770            finally771            {772                if (hService != IntPtr.Zero)773                {774                    bool succeeded = NativeMethods.CloseServiceHandle(hService);775                    Diagnostics.Assert(succeeded, "Failed to close service handle");776                }777            }778 779            PSObject serviceAsPSObj = PSObject.AsPSObject(service);780            PSNoteProperty noteProperty = new("UserName", startName);781            serviceAsPSObj.Properties.Add(noteProperty, true);782            serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#UserName");783 784            noteProperty = new PSNoteProperty("Description", description);785            serviceAsPSObj.Properties.Add(noteProperty, true);786            serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#Description");787 788            noteProperty = new PSNoteProperty("DelayedAutoStart", isDelayedAutoStart);789            serviceAsPSObj.Properties.Add(noteProperty, true);790            serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#DelayedAutoStart");791 792            noteProperty = new PSNoteProperty("BinaryPathName", binPath);793            serviceAsPSObj.Properties.Add(noteProperty, true);794            serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#BinaryPathName");795 796            noteProperty = new PSNoteProperty("StartupType", startupType);797            serviceAsPSObj.Properties.Add(noteProperty, true);798            serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#StartupType");799 800            return serviceAsPSObj;801        }802    }803#nullable disable804    #endregion GetServiceCommand805 806    #region ServiceOperationBaseCommand807    /// <summary>808    /// This class implements the base for service commands which actually809    /// act on the service(s).810    /// </summary>811    public abstract class ServiceOperationBaseCommand : MultipleServiceCommandBase812    {813        #region Parameters814        /// <summary>815        /// Gets/sets an array of service names.816        /// </summary>817        /// <remarks>818        /// The ServiceName parameter is declared in subclasses,819        /// since it is optional for GetService and mandatory otherwise.820        /// </remarks>821        [Parameter(Position = 0, ParameterSetName = "Default", Mandatory = true, ValueFromPipelineByPropertyName = true, ValueFromPipeline = true)]822        [Alias("ServiceName")]823        public string[] Name824        {825            get826            {827                return serviceNames;828            }829 830            set831            {832                serviceNames = value;833                selectionMode = SelectionMode.ServiceName;834            }835        }836 837        /// <summary>838        /// Service controller objects.839        /// </summary>840        [Parameter(Position = 0, Mandatory = true, ParameterSetName = "InputObject", ValueFromPipeline = true)]841        [ValidateNotNullOrEmpty]842        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]843        public new ServiceController[] InputObject844        {845            get846            {847                return base.InputObject;848            }849 850            set851            {852                base.InputObject = value;853            }854        }855 856        /// <summary>857        /// Specifies whether to write the objects successfully operated upon858        /// to the success stream.859        /// </summary>860        [Parameter]861        public SwitchParameter PassThru { get; set; }862 863        #endregion Parameters864 865        #region Internal866        /// <summary>867        /// Waits forever for the service to reach the desired status, but868        /// writes a string to WriteWarning every 2 seconds.869        /// </summary>870        /// <param name="serviceController">Service on which to operate.</param>871        /// <param name="targetStatus">Desired status.</param>872        /// <param name="pendingStatus">873        /// This is the expected status while the operation is incomplete.874        /// If the service is in some other state, this means that the875        /// operation failed.876        /// </param>877        /// <param name="resourceIdPending">878        /// resourceId for a string to be written to verbose stream879        /// every 2 seconds880        /// </param>881        /// <param name="errorId">882        /// errorId for a nonterminating error if operation fails883        /// </param>884        ///  <param name="errorMessage">885        /// errorMessage for a nonterminating error if operation fails886        /// </param>887        /// <returns>True if action succeeded.</returns>888        /// <exception cref="PipelineStoppedException">889        /// WriteWarning will throw this if the pipeline has been stopped.890        /// This means that the delay between hitting CTRL-C and stopping891        /// the cmdlet should be 2 seconds at most.892        /// </exception>893        internal bool DoWaitForStatus(894            ServiceController serviceController,895            ServiceControllerStatus targetStatus,896            ServiceControllerStatus pendingStatus,897            string resourceIdPending,898            string errorId,899            string errorMessage)900        {901            while (true)902            {903                try904                {905                    // ServiceController.Start will return before the service is actually started906                    // This API will wait forever907                    serviceController.WaitForStatus(908                        targetStatus,909                        new TimeSpan(20000000) // 2 seconds910                        );911                    return true; // service reached target status912                }913                catch (System.ServiceProcess.TimeoutException) // still waiting914                {915                    if (serviceController.Status != pendingStatus916                        // NTRAID#Windows Out Of Band Releases-919945-2005/09/27-JonN917                        // Close window where service could complete at918                        // just the wrong time919                        && serviceController.Status != targetStatus)920                    {921                        WriteNonTerminatingError(serviceController, null,922                                                 errorId,923                                                 errorMessage,924                                                 ErrorCategory.OpenError);925                        return false;926                    }927 928                    string message = StringUtil.Format(resourceIdPending,929                        serviceController.ServiceName,930                        serviceController.DisplayName931                        );932                    // will throw PipelineStoppedException if user hit CTRL-C933                    WriteWarning(message);934                }935            }936        }937 938        /// <summary>939        /// This will start the service.940        /// </summary>941        /// <param name="serviceController">Service to start.</param>942        /// <returns>True if-and-only-if the service was started.</returns>943        internal bool DoStartService(ServiceController serviceController)944        {945            Exception exception = null;946            try947            {948                serviceController.Start();949            }950            catch (Win32Exception e)951            {952                if (e.NativeErrorCode != NativeMethods.ERROR_SERVICE_ALREADY_RUNNING)953                    exception = e;954            }955            catch (InvalidOperationException e)956            {957                if (e.InnerException is not Win32Exception eInner958                    || eInner.NativeErrorCode != NativeMethods.ERROR_SERVICE_ALREADY_RUNNING)959                {960                    exception = e;961                }962            }963 964            if (exception != null)965            {966                // This service refused to accept the start command,967                // so write a non-terminating error.968                WriteNonTerminatingError(serviceController,969                    exception,970                    "CouldNotStartService",971                    ServiceResources.CouldNotStartService,972                    ErrorCategory.OpenError);973                return false;974            }975 976            // ServiceController.Start will return977            // before the service is actually started.978            if (!DoWaitForStatus(979                serviceController,980                ServiceControllerStatus.Running,981                ServiceControllerStatus.StartPending,982                ServiceResources.StartingService,983                "StartServiceFailed",984                ServiceResources.StartServiceFailed))985            {986                return false;987            }988 989            return true;990        }991 992        /// <summary>993        /// This will stop the service.994        /// </summary>995        /// <param name="serviceController">Service to stop.</param>996        /// <param name="force">Stop dependent services.</param>997        /// <param name="waitForServiceToStop"></param>998        /// <returns>True if-and-only-if the service was stopped.</returns>999        internal List<ServiceController> DoStopService(ServiceController serviceController, bool force, bool waitForServiceToStop)1000        {1001            // Ignore ServiceController.CanStop.  CanStop will be set false1002            // if the service is not running, but this is not an error.1003 1004            List<ServiceController> stoppedServices = new();1005            ServiceController[] dependentServices = null;1006 1007            try1008            {1009                dependentServices = serviceController.DependentServices;1010            }1011            catch (Win32Exception e)1012            {1013                WriteNonTerminatingError(serviceController, e,1014                    "CouldNotAccessDependentServices",1015                    ServiceResources.CouldNotAccessDependentServices,1016                    ErrorCategory.InvalidOperation);1017            }1018            catch (InvalidOperationException e)1019            {1020                WriteNonTerminatingError(serviceController, e,1021                    "CouldNotAccessDependentServices",1022                    ServiceResources.CouldNotAccessDependentServices,1023                    ErrorCategory.InvalidOperation);1024            }1025 1026            if (!force)1027            {1028                if ((dependentServices != null)1029                    && (dependentServices.Length > 0))1030                {1031                    // Check if all dependent services are stopped1032                    if (!HaveAllDependentServicesStopped(dependentServices))1033                    {1034                        // This service has dependent services1035                        //  and the force flag is not specified.1036                        //  Add a non-critical error for it.1037                        WriteNonTerminatingError(serviceController,1038                        null,1039                        "ServiceHasDependentServices",1040                        ServiceResources.ServiceHasDependentServices,1041                        ErrorCategory.InvalidOperation);1042 1043                        return stoppedServices;1044                    }1045                }1046            }1047 1048            if (dependentServices != null)1049            {1050                foreach (ServiceController service in dependentServices)1051                {1052                    if ((service.Status == ServiceControllerStatus.Running ||1053                        service.Status == ServiceControllerStatus.StartPending) &&1054                        service.CanStop)1055                    {1056                        stoppedServices.Add(service);1057                    }1058                }1059            }1060 1061            Exception exception = null;1062            try1063            {1064                serviceController.Stop();1065            }1066            catch (Win32Exception e)1067            {1068                if (e.NativeErrorCode != NativeMethods.ERROR_SERVICE_NOT_ACTIVE)1069                    exception = e;1070            }1071            catch (InvalidOperationException e)1072            {1073                if (e.InnerException is not Win32Exception eInner1074                    || eInner.NativeErrorCode != NativeMethods.ERROR_SERVICE_NOT_ACTIVE)1075                {1076                    exception = e;1077                }1078            }1079 1080            if (exception != null)1081            {1082                // This service refused to accept the stop command,1083                // so write a non-terminating error.1084                WriteNonTerminatingError(serviceController,1085                    exception,1086                    "CouldNotStopService",1087                    ServiceResources.CouldNotStopService,1088                    ErrorCategory.CloseError);1089                RemoveNotStoppedServices(stoppedServices);1090                return stoppedServices;1091            }1092 1093            // ServiceController.Stop will return1094            //  before the service is actually stopped.1095            if (waitForServiceToStop)1096            {1097                if (!DoWaitForStatus(1098                    serviceController,1099                    ServiceControllerStatus.Stopped,1100                    ServiceControllerStatus.StopPending,1101                    ServiceResources.StoppingService,1102                    "StopServiceFailed",1103                    ServiceResources.StopServiceFailed))1104                {1105                    RemoveNotStoppedServices(stoppedServices);1106                    return stoppedServices;1107                }1108            }1109 1110            RemoveNotStoppedServices(stoppedServices);1111            if ((serviceController.Status.Equals(ServiceControllerStatus.Stopped)) || (serviceController.Status.Equals(ServiceControllerStatus.StopPending)))1112            {1113                stoppedServices.Add(serviceController);1114            }1115 1116            return stoppedServices;1117        }1118 1119        /// <summary>1120        /// Check if all dependent services are stopped.1121        /// </summary>1122        /// <param name="dependentServices"></param>1123        /// <returns>1124        /// True if all dependent services are stopped1125        /// False if not all dependent services are stopped1126        /// </returns>1127        private static bool HaveAllDependentServicesStopped(ServiceController[] dependentServices)1128        {1129            return Array.TrueForAll(dependentServices, static service => service.Status == ServiceControllerStatus.Stopped);1130        }1131 1132        /// <summary>1133        /// This removes all services that are not stopped from a list of services.1134        /// </summary>1135        /// <param name="services">A list of services.</param>1136        internal void RemoveNotStoppedServices(List<ServiceController> services)1137        {1138            // You shall not modify a collection during enumeration.1139            services.RemoveAll(service =>1140                service.Status != ServiceControllerStatus.Stopped &&1141                service.Status != ServiceControllerStatus.StopPending);1142        }1143 1144        /// <summary>1145        /// This will pause the service.1146        /// </summary>1147        /// <param name="serviceController">Service to pause.</param>1148        /// <returns>True if-and-only-if the service was paused.</returns>1149        internal bool DoPauseService(ServiceController serviceController)1150        {1151            Exception exception = null;1152            bool serviceNotRunning = false;1153            try1154            {1155                serviceController.Pause();1156            }1157            catch (Win32Exception e)1158            {1159                if (e.NativeErrorCode == NativeMethods.ERROR_SERVICE_NOT_ACTIVE)1160                {1161                    serviceNotRunning = true;1162                }1163 1164                exception = e;1165            }1166            catch (InvalidOperationException e)1167            {1168                if (e.InnerException is Win32Exception eInner1169                    && eInner.NativeErrorCode == NativeMethods.ERROR_SERVICE_NOT_ACTIVE)1170                {1171                    serviceNotRunning = true;1172                }1173 1174                exception = e;1175            }1176 1177            if (exception != null)1178            {1179                // This service refused to accept the pause command,1180                // so write a non-terminating error.1181                string resourceIdAndErrorId = ServiceResources.CouldNotSuspendService;1182                if (serviceNotRunning)1183                {1184                    WriteNonTerminatingError(serviceController,1185                        exception,1186                        "CouldNotSuspendServiceNotRunning",1187                        ServiceResources.CouldNotSuspendServiceNotRunning,1188                        ErrorCategory.CloseError);1189                }1190                else if (!serviceController.CanPauseAndContinue)1191                {1192                    WriteNonTerminatingError(serviceController,1193                        exception,1194                        "CouldNotSuspendServiceNotSupported",1195                        ServiceResources.CouldNotSuspendServiceNotSupported,1196                        ErrorCategory.CloseError);1197                }1198 1199                WriteNonTerminatingError(serviceController,1200                    exception,

Showing the first 1,200 of 2947 lines. Download the file for the rest.