4191 lines · 195.0 KB · C#
RawDownload
//******************************************************************************************************//  ServiceHelper.cs - Gbtc////  Copyright © 2015, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  08/29/2006 - Pinal C. Patel//       Original version of source code generated.//  11/30/2007 - Pinal C. Patel//       Modified the "design time" check in EndInit() method to use LicenseManager. UsageMode property//       instead of DesignMode property as the former is more accurate than the latter.//  12/14/2007 - Pinal C. Patel//       Made monitoring of service health optional via the MonitorServiceHealth property.//  09/30/2008 - J. Ritchie Carroll//       Converted to C#.//  03/06/2009 - Pinal C. Patel//       Edited code comments.//  06/19/2009 - Pinal C. Patel//       Modified Initialize() method to just load settings from the config file.//  06/30/2009 - Pinal C. Patel//       Changed ServiceComponents to be a collection of object instead of ISupportLifecycle so it can//       host a wide range of object implementing various interfaces used by the ServiceHelper commands.//  07/15/2009 - Pinal C. Patel//       Added AllowedRemoteUsers and ImpersonateRemoteUser properties as part of security.//  07/16/2009 - Pinal C. Patel//       Added SupportTelnetSessions property so that telnet support can be optionally turned-on.//  07/17/2009 - Pinal C. Patel//       Modified MonitorServiceHealth to default to false as it is not always needed.//  07/30/2009 - Pinal C. Patel//       Modified to set the principal of the thread where client request are handled to that of the the //       process or remote client (if transmitted by the remote client upon connection).//  08/07/2009 - Pinal C. Patel//       Subscribed to ErrorLogger.LoggingException event.//  08/10/2009 - Josh L. Patterson//       Edited Comments//  09/08/2009 - Pinal C. Patel//       Modified GetProcess(), GetConnectedClient() and GetClientRequestHandler() to use lambda//       functions instead of manual iteration of collection items.//       Renamed GetProcess(), GetConnectedClient() and GetClientRequestHandler() to FindProcess(), //       FindConnectedClient() and FindClientRequestHandler() respectively.//  09/14/2009 - Stephen C. Wills//       Added new header and license agreement.//  10/23/2009 - Pinal C. Patel//       Modified UpdateStatus() method to allow the type of update to be specified.//  12/18/2009 - Pinal C. Patel//       Added message flooding control to UpdateStatus().//  06/16/2010 - Pinal C. Patel//       Made changes necessary to implement role-based security.//       Added thread synchronization to list-based member variable.//  10/14/2010 - Pinal C. Patel//       Updated security implementation to include the entire client request text including command //       and arguments instead of just the command.//  12/16/2010 - Pinal C. Patel//       Added SupportSystemCommands property that can be used to enable or disable system-level access //       via the build-in commands.//  01/04/2011 - J. Ritchie Carroll//       Changed default performance sampling interval on services to every 5 seconds instead of every//       second to reduce overhead and increase performance. Added a "-lifetime" option to the Health//       command to show lifetime performance statistics. Made sampling interval a user config option.//  01/17/2011 - J. Ritchie Carroll//       Added default "version" and "time" service commands.//  02/11/2011 - Pinal C. Patel//       Updated VerifySecurity() to work correctly with TCP integrated windows authentication. //  03/09/2011 - Pinal C. Patel//       Moved UpdateType enumeration to GSF namespace in GSF.Core.dll for broader usage.//  04/14/2011 - Pinal C. Patel//       Updated to use new serialization methods in GSF.Serialization class.//  09/22/2011 - J. Ritchie Carroll//       Added Mono implementation exception regions.//  02/17/2012 - Stephen C. Wills//       Added ReloadCryptoCache service command.//  04/12/2012 - Pinal C. Patel//       Added new UnscheduleProcess() and RemoveScheduledProcess methods.//       Changed AddProcess(), AddScheduledProcess() and ScheduleProcess() method to return a boolean.//  12/20/2012 - Starlynn Danyelle Gilliam//       Modified Header.////****************************************************************************************************** using GSF.Annotations;using GSF.Collections;using GSF.Communication;using GSF.Configuration;using GSF.Diagnostics;using GSF.ErrorManagement;using GSF.IO;using GSF.Reflection;using GSF.Scheduling;using GSF.Security;using GSF.Security.Cryptography;using GSF.Units;using System;using System.Collections.Generic;using System.ComponentModel;using System.Configuration;using System.Diagnostics;using System.Drawing;using System.IO;using System.Linq;using System.Reflection;using System.Security;using System.Security.Principal;using System.ServiceProcess;using System.Text;using System.Threading; namespace GSF.ServiceProcess{    #region [ Enumerations ]     /// <summary>    /// Indicates the state of a Windows Service.    /// </summary>    public enum ServiceState    {        /// <summary>        /// Service has started.        /// </summary>        Started,        /// <summary>        /// Service has stopped.        /// </summary>        Stopped,        /// <summary>        /// Service has paused.        /// </summary>        Paused,        /// <summary>        /// Service has resumed.        /// </summary>        Resumed,        /// <summary>        /// Service has shutdown.        /// </summary>        Shutdown    }     #endregion     /// <summary>    /// Component that provides added functionality to a Windows Service.    /// </summary>    /// <seealso cref="ServiceProcess"/>    /// <seealso cref="ServiceResponse"/>    /// <seealso cref="ClientInfo"/>    /// <seealso cref="ClientRequest"/>    /// <seealso cref="ClientRequestHandler"/>    [ToolboxBitmap(typeof(ServiceHelper))]    public class ServiceHelper : Component, ISupportLifecycle, ISupportInitialize, IProvideStatus, IPersistSettings    {        #region [ Members ]         // Nested Types        private class StatusUpdate        {            public StatusUpdate(Guid client, UpdateType type, string message)            {                this.Client = client;                this.Type = type;                this.Message = message;            }             public readonly Guid Client;            public readonly UpdateType Type;            public readonly string Message;        }         // Delegates        private delegate bool TryGetClientPrincipalFunctionSignature(Guid clientID, out WindowsPrincipal clientPrincipal);         // Constants         /// <summary>        /// Specifies the default value for the <see cref="LogStatusUpdates"/> property.        /// </summary>        public const bool DefaultLogStatusUpdates = true;         /// <summary>        /// Specifies the default value for the <see cref="MaxStatusUpdatesLength"/> property.        /// </summary>        public const int DefaultMaxStatusUpdatesLength = 8192;         /// <summary>        /// Specifies the default value for the <see cref="MaxStatusUpdatesFrequency"/> property.        /// </summary>        public const int DefaultMaxStatusUpdatesFrequency = 30;         /// <summary>        /// Specifies the default value for the <see cref="MonitorServiceHealth"/> property.        /// </summary>        public const bool DefaultMonitorServiceHealth = false;         /// <summary>        /// Specifies the default value for the <see cref="HealthMonitorInterval"/> property.        /// </summary>        public const double DefaultHealthMonitorInterval = 5.0D;         /// <summary>        /// Specifies the default value for the <see cref="RequestHistoryLimit"/> property.        /// </summary>        public const int DefaultRequestHistoryLimit = 50;         /// <summary>        /// Specifies the default value for the <see cref="SupportTelnetSessions"/> property.        /// </summary>        public const bool DefaultSupportTelnetSessions = false;         /// <summary>        /// Specifies the default value for the <see cref="SupportSystemCommands"/> property.        /// </summary>        public const bool DefaultSupportSystemCommands = false;         /// <summary>        /// Specifies the default value for the <see cref="SecureRemoteInteractions"/> property.        /// </summary>        public const bool DefaultSecureRemoteInteractions = false;         /// <summary>        /// Specifies the default value for the <see cref="ServiceHelper.SerializationFormat"/> property.        /// </summary>        public const SerializationFormat DefaultSerializationFormat = SerializationFormat.Binary;         /// <summary>        /// Specifies the default value for the <see cref="PersistSettings"/> property.        /// </summary>        public const bool DefaultPersistSettings = false;         /// <summary>        /// Specifies the default value for the <see cref="SettingsCategory"/> property.        /// </summary>        public const string DefaultSettingsCategory = "ServiceHelper";         // Events         /// <summary>        /// Occurs when the <see cref="ParentService"/> is starting.        /// </summary>        [Category("Service"),        Description("Occurs when the ParentService is starting.")]        public event EventHandler<EventArgs<string[]>> ServiceStarting;         /// <summary>        /// Occurs when the <see cref="ParentService"/> has started.        /// </summary>        [Category("Service"),        Description("Occurs when the ParentService has started.")]        public event EventHandler ServiceStarted;         /// <summary>        /// Occurs when the <see cref="ParentService"/> is stopping.        /// </summary>        [Category("Service"),        Description("Occurs when the ParentService is stopping.")]        public event EventHandler ServiceStopping;         /// <summary>        /// Occurs when the <see cref="ParentService"/> has stopped.        /// </summary>        [Category("Service"),        Description("Occurs when the ParentService has stopped.")]        public event EventHandler ServiceStopped;         /// <summary>        /// Occurs when the <see cref="ParentService"/> is pausing.        /// </summary>        [Category("Service"),        Description("Occurs when the ParentService is pausing.")]        public event EventHandler ServicePausing;         /// <summary>        /// Occurs when the <see cref="ParentService"/> has paused.        /// </summary>        [Category("Service"),        Description("Occurs when the ParentService has paused.")]        public event EventHandler ServicePaused;         /// <summary>        /// Occurs when the <see cref="ParentService"/> is resuming.        /// </summary>        [Category("Service"),        Description("Occurs when the ParentService is resuming.")]        public event EventHandler ServiceResuming;         /// <summary>        /// Occurs when the <see cref="ParentService"/> has resumed.        /// </summary>        [Category("Service"),        Description("Occurs when the ParentService has resumed.")]        public event EventHandler ServiceResumed;         /// <summary>        /// Occurs when the system is being shutdown.        /// </summary>        [Category("System"),        Description("Occurs when the system is being shutdown.")]        public event EventHandler SystemShutdown;         /// <summary>        /// Occurs when a request is received from one of the <see cref="RemoteClients"/>.        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T1,T2}.Argument1"/> is the ID of the remote client that sent the request.<br/>        /// <see cref="EventArgs{T1,T2}.Argument2"/> is the <see cref="ClientRequest"/> sent by the remote client.        /// </remarks>        [Category("Client"),        Description("Occurs when a request is received from one of the RemoteClients.")]        public event EventHandler<EventArgs<Guid, ClientRequest>> ReceivedClientRequest;         /// <summary>        /// Occurs when the state of a defined <see cref="ServiceProcess"/> changes.        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T1,T2}.Argument1"/> is the <see cref="ServiceProcess.Name"/>.<br/>        /// <see cref="EventArgs{T1,T2}.Argument2"/> is the <see cref="ServiceProcess.CurrentState"/>        /// </remarks>        [Category("Process"),        Description("Occurs when the state of a defined ServiceProcess changes.")]        public event EventHandler<EventArgs<string, ServiceProcessState>> ProcessStateChanged;         /// <summary>        /// Provides notification of when status messages were sent to consumer(s).        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T1,T2}.Argument1"/> is the status message sent to consumer(s).<br/>        /// <see cref="EventArgs{T1,T2}.Argument2"/> is the message <see cref="UpdateType"/>.        /// </remarks>        [Category("Notification"),        Description("Occurs when there are status messages sent to consumer(s).")]        public event EventHandler<EventArgs<string, UpdateType>> UpdatedStatus;         /// <summary>        /// Provides notification of when there is an exception logged.        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T}.Argument"/> is the exception that was logged.        /// </remarks>        [Category("Notification"),        Description("Occurs when there is an exception logged.")]        public event EventHandler<EventArgs<Exception>> LoggedException;         // Fields        private bool m_logStatusUpdates;        private int m_maxStatusUpdatesLength;        private int m_maxStatusUpdatesFrequency;        private bool m_monitorServiceHealth;        private double m_healthMonitorInterval;        private int m_requestHistoryLimit;        private bool m_supportTelnetSessions;        private bool m_supportSystemCommands;        private bool m_secureRemoteInteractions;        private SerializationFormat m_serializationFormat;        private bool m_persistSettings;        private string m_settingsCategory;        private string m_telnetSessionPassword;        private ServiceBase m_parentService;        private ServerBase m_remotingServer;        private readonly LogFile m_statusLog;        private readonly ScheduleManager m_processScheduler;        private readonly ErrorLogger m_errorLogger;        private PerformanceMonitor m_performanceMonitor;        private readonly List<ServiceProcess> m_processes;        private readonly List<object> m_serviceComponents;        private readonly List<ClientInfo> m_remoteClients;        private readonly List<ClientRequestInfo> m_clientRequestHistory;        private readonly List<ClientRequestHandler> m_clientRequestHandlers;        private readonly Dictionary<ISupportLifecycle, bool> m_componentEnabledStates;        private TryGetClientPrincipalFunctionSignature m_tryGetClientPrincipalFunction;        private readonly ProcessQueue<StatusUpdate> m_statusUpdateQueue;        private bool m_suppressUpdates;        private Guid m_remoteCommandClientID;        private Process m_remoteCommandProcess;        private Ticks m_lastStatusUpdateTime;        private long m_statusUpdateCount;        private bool m_supressStatusUpdates;        private bool m_enabled;        private bool m_initialized;        private bool m_disposed;         #endregion         #region [ Constructors ]         /// <summary>        /// Initializes a new instance of the <see cref="ServiceHelper"/> class.        /// </summary>        public ServiceHelper()        {            m_telnetSessionPassword = "s3cur3";            m_logStatusUpdates = DefaultLogStatusUpdates;            m_maxStatusUpdatesLength = DefaultMaxStatusUpdatesLength;            m_maxStatusUpdatesFrequency = DefaultMaxStatusUpdatesFrequency;            m_monitorServiceHealth = DefaultMonitorServiceHealth;            m_healthMonitorInterval = DefaultHealthMonitorInterval;            m_requestHistoryLimit = DefaultRequestHistoryLimit;            m_supportTelnetSessions = DefaultSupportTelnetSessions;            m_supportSystemCommands = DefaultSupportSystemCommands;            m_secureRemoteInteractions = DefaultSecureRemoteInteractions;            m_serializationFormat = DefaultSerializationFormat;            m_persistSettings = DefaultPersistSettings;            m_settingsCategory = DefaultSettingsCategory;            m_processes = new List<ServiceProcess>();            m_remoteClients = new List<ClientInfo>();            m_clientRequestHistory = new List<ClientRequestInfo>();            m_serviceComponents = new List<object>();            m_clientRequestHandlers = new List<ClientRequestHandler>();            m_componentEnabledStates = new Dictionary<ISupportLifecycle, bool>();             // Components            m_statusUpdateQueue = ProcessQueue<StatusUpdate>.CreateRealTimeQueue(ProcessStatusUpdates);            m_statusUpdateQueue.Name = "StatusUpdateQueue";            m_statusUpdateQueue.ProcessException += StatusUpdateQueue_ProcessException;             m_statusLog = new LogFile();            m_statusLog.FileName = "StatusLog.txt";            m_statusLog.SettingsCategory = "StatusLog";            m_statusLog.LogException += StatusLog_LogException;             m_processScheduler = new ScheduleManager();            m_processScheduler.SettingsCategory = "ProcessScheduler";            m_processScheduler.ScheduleDue += Scheduler_ScheduleDue;             m_errorLogger = new ErrorLogger();            m_errorLogger.ExitOnUnhandledException = false;            m_errorLogger.SettingsCategory = "ErrorLogger";            m_errorLogger.ErrorLog.SettingsCategory = "ErrorLog";            m_errorLogger.LoggingException += ErrorLogger_LoggingException;        }         /// <summary>        /// Initializes a new instance of the <see cref="ServiceHelper"/> class.        /// </summary>        /// <param name="container"><see cref="IContainer"/> object that contains the <see cref="ServiceHelper"/>.</param>        public ServiceHelper(IContainer container)            : this()        {            if ((object)container != null)                container.Add(this);        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets or sets a boolean value that indicates whether messages sent using <see cref="UpdateStatus(UpdateType,string,object[])"/>         /// or <see cref="UpdateStatus(Guid,UpdateType,string,object[])"/> are to be logged to the <see cref="StatusLog"/>.        /// </summary>        [Category("Updates"),        DefaultValue(DefaultLogStatusUpdates),        Description("Indicates whether messages sent using UpdateStatus() method overloads are to be logged to the StatusLog.")]        public bool LogStatusUpdates        {            get            {                return m_logStatusUpdates;            }            set            {                m_logStatusUpdates = value;            }        }         /// <summary>        /// Gets or sets the maximum numbers of characters allowed in update status messages without getting suppressed from being displayed.        /// </summary>        /// <exception cref="ArgumentException">The value being assigned is negative or zero.</exception>        [Category("Updates"),        DefaultValue(DefaultMaxStatusUpdatesLength),        Description("Maximum numbers of characters allowed in update status messages without getting suppressed from being displayed.")]        public int MaxStatusUpdatesLength        {            get            {                return m_maxStatusUpdatesLength;            }            set            {                if (value <= 0)                    throw new ArgumentException("Value must be positive");                 m_maxStatusUpdatesLength = value;            }        }         /// <summary>        /// Gets or sets the maximum number of status update messages that can be issued in a second without getting suppressed from being displayed.        /// </summary>        /// <exception cref="ArgumentException">The value being assigned is negative or zero.</exception>

Lines 1–500 of 4191.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t