📄 systemtrayobserver.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 + -