//******************************************************************************************************// 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. Load more
//****************************************************************************************************** // 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>