ServiceInstallComponent.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Tools / xws_reg / System / ServiceModel / Install / ServiceInstallComponent.cs / 1 / ServiceInstallComponent.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Install
{ 
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Globalization; 
    using System.IO;
    using System.Runtime.InteropServices; 
    using System.Security.Principal;
    using System.ServiceProcess;
    using System.Text;
 
    // NOTE: This class is *not* free-threaded.
    abstract class ServiceInstallComponent : ServiceModelInstallComponent 
    { 
        string accountName;
        string[] dependsOn; 
        string description;
        string displayName;
        string exeName;
        string exeParams; 
        static readonly TimeSpan FailureResetPeriod = TimeSpan.FromMinutes(15);
        static readonly TimeSpan[] FailureRestartPeriods = 
            new TimeSpan[] {TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(5)}; 
        string legacyServiceName;
        static string scPath; 
        string securityDescriptor;
        static LUID securityPrivilege;
        static bool securityPrivilegeInitialized;
        string serviceName; 
        ServiceStartMode startType;
 
        static readonly int[] StopServiceOkExitCodes = 
            {
                ErrorCodes.ERROR_SUCCESS, ErrorCodes.ERROR_SERVICE_NOT_ACTIVE 
            };

        protected ServiceInstallComponent(string serviceName, string legacyServiceName, string displayName,
            ServiceStartMode startType, string exeName, string exeParams, string[] dependsOn, string accountName, 
            string description, string securityDescriptor)
        { 
            this.serviceName = serviceName; 
            this.legacyServiceName = legacyServiceName;
            this.displayName = displayName; 
            this.startType = startType;
            this.exeName = exeName;
            this.exeParams = exeParams;
            this.dependsOn = dependsOn; 
            this.accountName = accountName;
            this.description = description; 
            this.securityDescriptor = securityDescriptor; 
        }
 
        internal override string DisplayName
        {
            get {return String.Format(CultureInfo.CurrentCulture, "{0} ({1})", this.displayName, this.serviceName); }
        } 

        protected override string InstallActionMessage 
        { 
            get {return SR.GetString(SR.ServiceInstall, this.DisplayName); }
        } 

        internal override string[] InstalledVersions
        {
            get 
            {
                string binaryPathName = null; 
                using (ServiceManagerHandle serviceManager = ServiceManagerHandle.OpenServiceManager()) 
                {
                    try 
                    {
                        using (ServiceHandle service = serviceManager.OpenService(this.serviceName,
                            NativeMethods.SERVICE_QUERY_CONFIG))
                        { 
                            QUERY_SERVICE_CONFIG serviceConfig = service.QueryServiceConfig();
                            binaryPathName = serviceConfig.lpBinaryPathName; 
                        } 
                    }
                    catch (Win32Exception exception) 
                    {
                        if (!IsServiceNotFoundError(exception))
                        {
#pragma warning suppress 56503 // [....]; not a publicly accessible API 
                            throw;
                        } 
                    } 
                }
 
                string[] result;
                if (!String.IsNullOrEmpty(binaryPathName))
                {
                    result = new string[] {String.Format(CultureInfo.InvariantCulture, "{0}", binaryPathName)}; 
                }
                else 
                { 
                    result = new string[] {};
                } 

                return result;
            }
        } 

        internal override bool IsInstalled 
        { 
            get
            { 
                return IsServiceInstalled(this.serviceName);
            }
        }
 
        protected override string ReinstallActionMessage
        { 
            get {return SR.GetString(SR.ServiceReinstall, this.DisplayName); } 
        }
 
        static string SCPath
        {
            get
            { 
                if (String.IsNullOrEmpty(ServiceInstallComponent.scPath))
                { 
                    ServiceInstallComponent.scPath = Path.Combine(Environment.SystemDirectory, @"sc.exe"); 
                }
                return ServiceInstallComponent.scPath; 
            }
        }

        static LUID SecurityPrivilege 
        {
            get 
            { 
                if (!securityPrivilegeInitialized)
                { 
#pragma warning suppress 56523 // [....]; Win32Exception default constructor calls Marshal.GetLastWin32Error() internally.
                    if (!NativeMethods.LookupPrivilegeValue(null, NativeMethods.SE_SECURITY_NAME,
                        out securityPrivilege))
                    { 
#pragma warning suppress 56503 // [....]; not a publicly accessible API
                        throw new Win32Exception(); 
                    } 
                    securityPrivilegeInitialized = true;
                } 
                return securityPrivilege;
            }
        }
 
        protected string ServiceName
        { 
            get 
            {
                return this.serviceName; 
            }
        }

        protected override string UninstallActionMessage 
        {
            get {return SR.GetString(SR.ServiceUninstall, this.DisplayName); } 
        } 

        static void AdjustSecurityPrivilege(int attributes) 
        {
            using (SafeTokenHandle tokenHandle = GetProcessToken())
            {
                TOKEN_PRIVILEGES privileges; 
                privileges.PrivilegeCount = 1;
                privileges.Privilege.Luid = SecurityPrivilege; 
                privileges.Privilege.Attributes = attributes; 
                bool success = NativeMethods.AdjustTokenPrivileges(tokenHandle, false, ref privileges, 0, IntPtr.Zero,
                    IntPtr.Zero); 
                int errorCode = Marshal.GetLastWin32Error();
                if (!success || (errorCode != ErrorCodes.ERROR_SUCCESS))
                {
                    throw new Win32Exception(errorCode); 
                }
            } 
        } 

        void DeleteService() 
        {
            DeleteService(this.serviceName);
        }
 
        protected static void DeleteService(string serviceName)
        { 
            using (ServiceManagerHandle serviceManager = ServiceManagerHandle.OpenServiceManager()) 
            {
                using (ServiceHandle service = serviceManager.OpenService(serviceName, NativeMethods.DELETE)) 
                {
                    try
                    {
                        service.Delete(); 
                    }
                    catch (Win32Exception exception) 
                    { 
                        if (exception.NativeErrorCode != ErrorCodes.ERROR_SERVICE_MARKED_FOR_DELETE)
                        { 
                            throw;
                        }
                    }
                } 
            }
        } 
 
        protected static void ExecuteSC(string parameters, params int[] allowedExitCodes)
        { 
            InstallHelper.ExecuteWait(SCPath, parameters, allowedExitCodes);
        }

        string GetCommandLine() 
        {
            string installPath = InstallHelper.GetNativeWcfRuntimeInstallPath(); 
            string commandLine = String.Format(CultureInfo.InvariantCulture, "\"{0}\"", Path.Combine(installPath, this.exeName)); 
            if (this.exeParams != null)
            { 
                commandLine = string.Format(CultureInfo.InvariantCulture, "{0} {1}", commandLine, this.exeParams);
            }
            return commandLine;
        } 

        string GetDependencies() 
        { 
            string dependencies = null;
            if (this.dependsOn != null) 
            {
                StringBuilder builder = new StringBuilder();
                foreach (string dependency in this.dependsOn)
                { 
                    builder.AppendFormat("{0}\0", dependency);
                } 
                dependencies = builder.ToString(); 
            }
            return dependencies; 
        }

        static SafeTokenHandle GetProcessToken()
        { 
            SafeTokenHandle tokenHandle;
#pragma warning suppress 56523 // [....]; Win32Exception default constructor calls Marshal.GetLastWin32Error() internally. 
            if (!NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle, 
                NativeMethods.TOKEN_ADJUST_PRIVILEGES, out tokenHandle))
            { 
                throw new Win32Exception();
            }
            return tokenHandle;
        } 

        internal override void Install(OutputLevel outputLevel) 
        { 
            if (this.IsInstalled)
            { 
                EventLogger.LogWarning(SR.GetString(SR.ServiceAlreadyExists, this.DisplayName),
                    (OutputLevel.Verbose == outputLevel));
            }
            else 
            {
                this.OnInstall(outputLevel); 
            } 
        }
 
        protected static bool IsServiceInstalled(string serviceName)
        {
            bool result;
            using (ServiceManagerHandle serviceManager = ServiceManagerHandle.OpenServiceManager()) 
            {
                try 
                { 
                    using (ServiceHandle service = serviceManager.OpenService(serviceName,
                        NativeMethods.SERVICE_QUERY_CONFIG)) 
                    {
                        result = true;
                    }
                } 
                catch (Win32Exception exception)
                { 
                    if (IsServiceNotFoundError(exception)) 
                    {
                        result = false; 
                    }
                    else
                    {
                        throw; 
                    }
                } 
            } 
            return result;
        } 

        static bool IsServiceNotFoundError(Win32Exception exception)
        {
            return ((exception.NativeErrorCode == ErrorCodes.ERROR_SERVICE_DOES_NOT_EXIST) || 
                (exception.NativeErrorCode == ErrorCodes.ERROR_SERVICE_NOT_FOUND));
        } 
 
        protected virtual void OnInstall(OutputLevel outputLevel)
        { 
            if ((this.legacyServiceName != null) && IsServiceInstalled(this.legacyServiceName))
            {
                // An earlier interim version of WCF had an uninstall bug in which some NT services would not be
                // deleted.  We recover from this state herein so that we don't experience a service display name 
                // collision when trying to install the latest version of the service (MB 52062 & 53344).
                DeleteService(this.legacyServiceName); 
            } 

            string commandLine = this.GetCommandLine(); 
            string dependencies = this.GetDependencies();

            using (ServiceManagerHandle serviceManager = ServiceManagerHandle.OpenServiceManager())
            { 
                AdjustSecurityPrivilege(NativeMethods.SE_PRIVILEGE_ENABLED);
                try 
                { 
                    using (ServiceHandle service = serviceManager.CreateService(this.serviceName, this.displayName,
                        NativeMethods.SERVICE_WIN32_SHARE_PROCESS, (int) this.startType, NativeMethods.SERVICE_ERROR_NORMAL, 
                        commandLine, dependencies, accountName))
                    {
                        service.SetDescription(this.description);
                        service.SetSecurityDescriptor(this.securityDescriptor); 
                        service.SetFailureActions(FailureResetPeriod, FailureRestartPeriods);
                    } 
                } 
                finally
                { 
                    AdjustSecurityPrivilege(NativeMethods.SE_PRIVILEGE_DISABLED);
                }
            }
        } 

        protected virtual void OnReinstall(OutputLevel outputLevel) 
        { 
            this.StopService(outputLevel);
 
            using (ServiceManagerHandle serviceManager = ServiceManagerHandle.OpenServiceManager())
            {
                using (ServiceHandle service = serviceManager.OpenService(this.serviceName,
                    NativeMethods.SERVICE_CHANGE_CONFIG)) 
                {
                    string commandLine = this.GetCommandLine(); 
                    string dependencies = this.GetDependencies(); 
                    service.ChangeServiceConfig(NativeMethods.SERVICE_WIN32_SHARE_PROCESS, commandLine, dependencies,
                        this.displayName); 
                    service.SetDescription(this.description);
                }
            }
        } 

        protected virtual void OnUninstall(OutputLevel outputLevel) 
        { 
            this.StopService(outputLevel);
            this.DeleteService(); 
        }

        internal override void Reinstall(OutputLevel outputLevel)
        { 
            if (OutputLevel.Quiet != outputLevel)
            { 
                EventLogger.LogToConsole(SR.GetString(SR.RepairMessage, this.DisplayName)); 
            }
 
            EventLogger.WriteMsiStyleLogEntry(SR.GetString(SR.RepairMessage, this.DisplayName));

            if (!this.IsInstalled)
            { 
                this.OnInstall(outputLevel);
            } 
            else 
            {
                this.OnReinstall(outputLevel); 
            }
        }

        void StopService(OutputLevel outputLevel) 
        {
            using (ServiceController controller = new ServiceController(this.serviceName)) 
            { 
                if ((controller.Status != ServiceControllerStatus.Stopped) &&
                    (controller.Status != ServiceControllerStatus.StopPending)) 
                {
                    try
                    {
                        controller.Stop(); 
                    }
                    catch (InvalidOperationException exception) 
                    { 
                        // The service is not in a valid state for stopping.  This would typically be due to a benign
                        // race condition, so ignore. 
                        EventLogger.LogWarning(SR.GetString(SR.ErrorStoppingService, this.serviceName, exception),
                            (OutputLevel.Verbose == outputLevel));
                    }
                    catch (Win32Exception exception) 
                    {
                        if (!InstallHelper.IsExitCodeAllowed(StopServiceOkExitCodes, exception.NativeErrorCode)) 
                        { 
                            throw;
                        } 
                    }
                }

                try 
                {
                    controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30)); 
                } 
                catch (TimeoutException)
                { 
                    EventLogger.LogWarning(SR.GetString(SR.ServiceCouldNotBeStopped, this.serviceName),
                        (OutputLevel.Verbose == outputLevel));
                }
            } 
        }
 
        internal override void Uninstall(OutputLevel outputLevel) 
        {
            if (!this.IsInstalled) 
            {
                EventLogger.LogWarning(SR.GetString(SR.ServiceNotInstalled, this.DisplayName),
                    (OutputLevel.Verbose == outputLevel));
            } 
            else
            { 
                this.OnUninstall(outputLevel); 
            }
        } 

        internal override InstallationState VerifyInstall()
        {
            // We don't currently go to the trouble of comparing all the service's config settings against defaults. 
            return this.IsInstalled ? InstallationState.InstalledDefaults : InstallationState.NotInstalled;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK