⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 systemtrayobserver.cs

📁 Oracle Service Manager
💻 CS
字号:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Reflection;
using System.Resources;
using System.ServiceProcess;
using System.Threading;
using System.Windows.Forms;
using kae.ServiceStatePublisher;

namespace kae.OracleServiceManager
{
	/// <summary>
	/// SystemTrayObserver is a concrete observer listening to the current subject for changes.
	/// SystemTrayObserver manages the tray icon interface for OSM.
	/// </summary>
	public class SystemTrayObserver : Container
	{
		protected delegate void UpdateFunction( ServiceSubject subject);

		private const int INDEX_SERVICESMENU = 1;

		private readonly string START;
		private readonly string CONTINUE;
		private readonly string PAUSE;
		private readonly string STOP;

		private OsmResources _resources;
		private NotifyIcon _trayIcon;
		private MenuItem _availableServicesMenu;
		private MenuItem _startServiceMenuItem;
		private MenuItem _stopServiceMenuItem;
		private MenuItem _pauseServiceMenuItem;
		private MenuItem _currentServiceMenuItem;
		private bool _updating;
		private EventHandler onMenuItemClick;
		private UpdateFunction serverChanged;
		private UpdateFunction serviceChanged;
		private UpdateFunction serviceStateChanged;

		public SystemTrayObserver( ServiceSubject subject)
		{
			if (subject != null)
			{
				subject.ServerChanged += new EventHandler( this.OnServerChanged);
				subject.ServiceChanged += new EventHandler( this.OnServiceChanged);
				subject.StateChanged += new EventHandler( this.OnStateChanged);
			}

			serverChanged = new UpdateFunction( this.ServerChanged);
			serviceChanged = new UpdateFunction( this.ServiceChanged);
			serviceStateChanged = new UpdateFunction( this.ServiceStateChanged);
			onMenuItemClick = new EventHandler( this.ServiceItemClick);

			_resources = OracleServiceManager.Instance.Resources;
			START = GetAppString( "Start");
			CONTINUE = GetAppString( "Continue");
			PAUSE = GetAppString( "Pause");
			STOP = GetAppString( "Stop");

			InitializeComponent();
		}

		protected override void Dispose( bool disposing)
		{
			if (disposing)
			{
				_availableServicesMenu.Dispose();
				_availableServicesMenu = null;
				_startServiceMenuItem.Dispose();
				_startServiceMenuItem = null;
				_stopServiceMenuItem.Dispose();
				_stopServiceMenuItem = null;
				_pauseServiceMenuItem.Dispose();
				_pauseServiceMenuItem = null;
				_currentServiceMenuItem = null;

				if (_trayIcon != null)
				{
					_trayIcon.Icon = null;
					_trayIcon.Text = null;
					_trayIcon.ContextMenu = null;
					_trayIcon.Dispose();
				}
			}
			base.Dispose( disposing);
		}

		protected bool Updating
		{
			get { return _updating; }
			set { _updating = value; }
		}

		#region Manually generated initialization code
		private void InitializeComponent()
		{
			_trayIcon = new System.Windows.Forms.NotifyIcon( this);
			_trayIcon.Icon = _resources.GetApplicationImage();
			_trayIcon.Visible = true;
			SetDefaultTrayIconText();
			_trayIcon.ContextMenu = new ContextMenu();
			_trayIcon.DoubleClick += new EventHandler( this.NotifyIconDoubleClick);

			string menuLabel = GetStringFromResources( "About");
			MenuItem aboutMenuItem = new MenuItem( menuLabel, new EventHandler( this.AboutClick));
			menuLabel = GetStringFromResources( "Options");
			MenuItem optionsMenuItem = new MenuItem( menuLabel, new EventHandler( this.OptionsClick));
			menuLabel = GetStringFromResources( "Exit");
			MenuItem exitMenuItem = new MenuItem( menuLabel, new EventHandler( this.ExitClick));
			_stopServiceMenuItem = new MenuItem( STOP, new EventHandler( this.StopClick));
			_stopServiceMenuItem.Enabled = false;
			_pauseServiceMenuItem = new MenuItem( PAUSE, new EventHandler( this.PauseClick));
			_pauseServiceMenuItem.Enabled = false;
			_startServiceMenuItem = new MenuItem( START, new EventHandler( this.StartClick));
			_startServiceMenuItem.Enabled = false;
			_availableServicesMenu = new MenuItem();
			DisableAvailableServicesMenu();
			menuLabel = GetStringFromResources( "OpenDialog");
			MenuItem osmMenuItem = new MenuItem( menuLabel, new EventHandler( this.OpenServiceManagerClick));
			osmMenuItem.DefaultItem = true;

			_trayIcon.ContextMenu.MenuItems.Add( 0, aboutMenuItem);
			_trayIcon.ContextMenu.MenuItems.Add( 0, optionsMenuItem);
			_trayIcon.ContextMenu.MenuItems.Add( 0, exitMenuItem);
			_trayIcon.ContextMenu.MenuItems.Add( 0, new MenuItem( "-"));
			_trayIcon.ContextMenu.MenuItems.Add( 0, _stopServiceMenuItem);
			_trayIcon.ContextMenu.MenuItems.Add( 0, _pauseServiceMenuItem);
			_trayIcon.ContextMenu.MenuItems.Add( 0, _startServiceMenuItem);
			_trayIcon.ContextMenu.MenuItems.Add( 0, new MenuItem( "-"));
			_trayIcon.ContextMenu.MenuItems.Add( 0, _availableServicesMenu);
			_trayIcon.ContextMenu.MenuItems.Add( 0, osmMenuItem);
		}
		#endregion
		
		#region Implementation of Listener/Observer
		protected void OnServerChanged( object sender, System.EventArgs e)
		{
			ServiceSubject subject = (ServiceSubject) sender;
			Update( serverChanged, subject);
		}

		protected void OnServiceChanged( object sender, System.EventArgs e)
		{
			ServiceSubject subject = (ServiceSubject) sender;
			Update( serviceChanged, subject);
		}

		protected void OnStateChanged( object sender, System.EventArgs e)
		{
			ServiceSubject subject = (ServiceSubject) sender;
			Update( serviceStateChanged, subject);
		}

		private void Update( UpdateFunction function, ServiceSubject subject)
		{
			if (!Updating)
			{
				Updating = true;

				function( subject);

				Updating = false;
			}
		}

		private void ServerChanged( ServiceSubject subject)
		{
			ClearCurrentServiceItem();
			SetDefaultActionMenuState();
			RemoveAvailableServicesItems();

			if (subject.ServerName != null)
			{
				string connected = GetStringFromResources( "Connected");
				RemoveAvailableServicesMenu();
				_availableServicesMenu = CreateAvailableServicesMenu( subject.ServerName);
				SetAvailableServicesMenu( subject.ServerName);
				SetTrayIconText( connected, subject.ServerName);
				SetDefaultTrayIconImage();
			}
			else
			{
				DisableAvailableServicesMenu();
				SetDefaultTrayIconText();
				SetDefaultTrayIconImage();
			}
		}

		private void ServiceChanged( ServiceSubject subject)
		{
			ClearCurrentServiceItem();

			if (subject.Controller != null)
			{
				string serviceName = subject.Controller.DisplayName;
				SetCurrentServiceItem( serviceName);
				SetActionMenuState( subject, serviceName);
				SetTrayIconText( subject.State.Status, subject.ServerName, serviceName);
				SetTrayIconImage( subject.State);
			}
			else
			{
				SetDefaultActionMenuState();
				SetDefaultTrayIconImage();
			}
		}

		private void ServiceStateChanged( ServiceSubject subject)
		{
			string serverName = subject.ServerName;
			string serviceName;
			
			if (subject.State != ServiceStateUnknown.Instance)
			{
				serviceName = subject.Controller.DisplayName;
				SetActionMenuState( subject, serviceName);
				SetTrayIconText( subject.State.Status, serverName, serviceName);
				SetTrayIconImage( subject.State);
			}
			else
			{
				SetDefaultActionMenuState();
				SetDefaultTrayIconImage();
			}
		}
		#endregion

		#region NotifyIcon support functions
		private void RemoveAvailableServicesMenu()
		{
			_trayIcon.ContextMenu.MenuItems.RemoveAt( INDEX_SERVICESMENU);
		}

		private MenuItem CreateAvailableServicesMenu( string serverName)
		{
			string format = GetStringFromResources( "CurrentService");
			MenuItem item = new MenuItem( String.Format( format, serverName));
			_trayIcon.ContextMenu.MenuItems.Add( INDEX_SERVICESMENU, item);
			return item;
		}

		private void DisableAvailableServicesMenu()
		{
			_availableServicesMenu.Text = GetStringFromResources( "NoServer");
			_availableServicesMenu.Enabled = false;
		}

		private void RemoveAvailableServicesItems()
		{
			_availableServicesMenu.MenuItems.Clear();
		}

		private void SetAvailableServicesMenu( string serverName)
		{
			AddOracleServicesToMenu( serverName);
			if (_availableServicesMenu.MenuItems.Count == 0)
			{
				string noServices = GetStringFromResources( "NoServices");
				MenuItem item = _availableServicesMenu.MenuItems.Add( noServices);
				item.Enabled = false;
			}
		}

		private void AddOracleServicesToMenu( string serverName)
		{
			ServiceController[] services = ServiceController.GetServices( serverName);

			if (services.Length > 0)
			{
				foreach (ServiceController service in services)
				{
					// HACK: Modify to monitor different databases
					if (service.ServiceName.StartsWith( "Oracle"))
						_availableServicesMenu.MenuItems.Add( service.ServiceName, onMenuItemClick);
				}
			}
		}

		private void ClearCurrentServiceItem()
		{
			if (_currentServiceMenuItem != null)
			{
				_currentServiceMenuItem.Checked = false;
				_currentServiceMenuItem = null;
			}
		}

		private void SetCurrentServiceItem( string serviceName)
		{
			foreach (MenuItem item in _availableServicesMenu.MenuItems)
			{
				if (item.Text.Equals( serviceName))
				{
					item.Checked = true;
					_currentServiceMenuItem = item;
					break;
				}
			}
		}

		private void SetDefaultTrayIconText()
		{
			_trayIcon.Text = _resources.ApplicationName;
		}

		private void SetTrayIconText( string status)
		{
			_trayIcon.Text = status;
		}

		private void SetTrayIconText( string status, string serverName)
		{
			_trayIcon.Text = String.Format( @"{0} - \\{1}", status, serverName);
		}

		private void SetTrayIconText( string status, string serverName, string serviceName)
		{
			_trayIcon.Text = String.Format( @"{0} - \\{1} - {2}", status, serverName, serviceName);
		}

		private void SetDefaultTrayIconImage()
		{
			SetTrayIconImage( ServiceStateUnknown.Instance);
		}

		private void SetTrayIconImage( ServiceState state)
		{
			_trayIcon.Icon = _resources.GetSmallStateImage( state);
		}

		private void SetDefaultActionMenuState()
		{
			SetActionItemInfo( START, _startServiceMenuItem, null, false);
			SetActionItemInfo( PAUSE, _pauseServiceMenuItem, null, false);
			SetActionItemInfo( STOP, _stopServiceMenuItem, null, false);
		}

		private void SetActionMenuState( ServiceSubject subject, string serviceName)
		{
			Debug.Assert( subject != null, "[SetActionMenuState] Subject cannot be null");

			string startOrContinue = (subject.State == ServiceStopped.Instance) ? START : CONTINUE;
			SetActionItemInfo( startOrContinue, _startServiceMenuItem, serviceName, subject.CanStart);
			SetActionItemInfo( PAUSE, _pauseServiceMenuItem, serviceName, subject.CanPause);
			SetActionItemInfo( STOP, _stopServiceMenuItem, serviceName, subject.CanStop);
		}

		private void SetActionItemInfo( string actionName, MenuItem menuItem, string serviceName, bool isEnabled)
		{
			menuItem.Enabled = isEnabled;

			if (serviceName != null)
				menuItem.Text = String.Format( @"{0} - {1}", actionName, serviceName);
			else
				menuItem.Text = actionName;
		}

		private bool VerifyUserAction( string action)
		{
			string serviceName = OracleServiceManager.Instance.Subject.Controller.DisplayName;
			string serverName = OracleServiceManager.Instance.Subject.ServerName;

			return OracleServiceManager.Instance.VerifyUserAction( action, serviceName, serverName);
		}

		private string GetStringFromResources( string name)
		{
			return _resources.GetString( typeof(SystemTrayObserver), name);
		}

		private string GetAppString( string name)
		{
			return _resources.GetAppString( name);
		}
		#endregion

		#region User action implementation
		private void NotifyIconDoubleClick( object sender, EventArgs e)
		{
			OpenServiceManagerClick( sender, e);
		}

		private void OptionsClick( object sender, EventArgs e)
		{
			OracleServiceManager.Instance.ConfigureOptions();
		}

		private void AboutClick( object sender, EventArgs e)
		{
			OracleServiceManager.Instance.ShowAboutDialog();
		}

		private void ExitClick( object sender, EventArgs e)
		{
			_trayIcon.Visible = false;
			OracleServiceManager.Instance.ExitThread();
		}

		private void StartClick( object sender, EventArgs e)
		{
			if (VerifyUserAction( START))
				OracleServiceManager.Instance.Subject.Start();
		}

		private void PauseClick( object sender, EventArgs e)
		{
			if (VerifyUserAction( PAUSE))
				OracleServiceManager.Instance.Subject.Pause();
		}

		private void StopClick( object sender, EventArgs e)
		{
			if (VerifyUserAction( PAUSE))
				OracleServiceManager.Instance.Subject.Stop();
		}

		private void ServiceItemClick( object sender, EventArgs e)
		{
			MenuItem menuItem = (MenuItem) sender;
			ServiceSubject subject = OracleServiceManager.Instance.Subject;

			subject.Controller = new ServiceController( menuItem.Text, subject.ServerName);
		}

		private void OpenServiceManagerClick( object sender, EventArgs e)
		{
			OracleServiceManager.Instance.OpenServiceManagerDialog();
		}
		#endregion
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -