Click here to Skip to main content
15,893,381 members
Articles / Programming Languages / C#

Watch Dog

Rate me:
Please Sign up or sign in to vote.
3.76/5 (22 votes)
5 Sep 2007CPOL4 min read 144.2K   3.3K   84  
Execute applications with a Windows Service and ensure its existance.
using System;
using System.Runtime.InteropServices;
using WatchDogPile;
using System.Diagnostics;


namespace WatchDogPile
{
	#region ProcessStatusEventArgs: Fires when Queue Engine starts or stops
	public class ProcessStatusEventArgs: EventArgs 
	{
		public ProcessStatusEventArgs(Process queueEngineProcess, bool isRunning)
		{
			QueueEngineProcess = queueEngineProcess;
			IsRunning = isRunning;
		}
		public Process QueueEngineProcess;
		public bool IsRunning;
	}    
	#endregion

	/// <summary>
	/// Summary description for AppWrapper.
	/// </summary>
	public class AppWrapper: ITrainingDog
	{
		#region override FindProcess
		/// <summary>
		/// Overrided find the spinning engine process
		/// </summary>
		/// <returns>The first process found with SpinningEngine.exe name </returns>
		public Process FindProcess()
		{
			if(PID>=0)
			{
				try
				{
					Process TheProcess = GetProcessByID();
					if(TheProcess == null)
					{
						OnProcessStatusChangedEvent(this, new ProcessStatusEventArgs( null, false) );
						return null;
					}
					else
					{
						OnProcessStatusChangedEvent(this, new ProcessStatusEventArgs( TheProcess, true) );
						return TheProcess;
					}
				}
				catch(Exception ex)
				{
					Console.Write("ISpin", "FindProcess: "+ex.Message, 
						System.Diagnostics.EventLogEntryType.Error, 0);
					return null;
				}
			}
			else
			{
				OnProcessStatusChangedEvent(this, new ProcessStatusEventArgs( null, false) );
				return null;
			}
		}
		#endregion

		#region override SuspectedSmell
		/// <summary>
		/// Is being used by a watch dog thread
		/// </summary>
		/// <returns>if the process is dead (Suspected) then return null </returns>
		public object SuspectedSmell()
		{
			try
			{
				Process TheProcess = GetProcessByID();
				if(TheProcess==null)
					return (bool)false;
				else
					return null;
			}
			catch
			{
				return (bool)true;
			}
		}
		#endregion 

		#region override StartUp
		public Process StartUp(string theApp2Watch)
		{
			/// Send the process a unique name
			Process p = StartUpProcess(theApp2Watch, "");
			
			// April 12, 05
			OnProcessStatusChangedEvent(this, new ProcessStatusEventArgs( theProcess, true) );

			return p;
		}
		#endregion

		#region override ShutDown
		public void ShutDown()
		{
			b_IsAlive = false;
			if(theProcess!=null)
			{
				if(GetProcessByID()!=null)
					theProcess.Kill();
				OnProcessStatusChangedEvent(this, new ProcessStatusEventArgs( null, false) );
			}
			else
				OnProcessStatusChangedEvent(this, new ProcessStatusEventArgs( theProcess, false) );
		}
		#endregion


		/// <summary>
		/// Is being use to destroy the hidden window in Spinning Engine
		/// </summary>
		/// <param name="hwnd"></param>
		/// <returns></returns>
		[DllImport("user32")] public static extern int SendMessage(int hwnd, int msg, int p1, int p2);
		
		/// <summary>
		/// Aug 27, 05: Bob
		/// </summary>
		protected int PID=-1; /// Process ID associated to this object
		
		protected Process theProcess=null;
		protected bool b_IsAlive=false;

		#region GetProcessByID
		/// <summary>
		/// Return the Process this object is manageing
		/// </summary>
		/// <returns>The process of this object PID</returns>
		protected Process GetProcessByID()
		{
			try
			{
				if(PID<0)
					return null;
				else
					return Process.GetProcessById(PID);
			}
			catch
			{
				return null;
			}
		}

		/// <summary>
		/// Set the PID for an object, It has been used in CCMUtil
		/// </summary>
		/// <param name="thPID"></param>
		public int ProcessID
		{
			get
			{
				return PID;
			}
			set
			{
				if(value<0)
					throw new Exception("Process ID cannot be negative.");
				PID = value;
			}
		}
		#endregion

		#region Process Status Event definitions
		public delegate void ProcessStatusEventHandler(object source, ProcessStatusEventArgs rea);
		public event ProcessStatusEventHandler ProcessStatusChangedEvent;
		protected void OnProcessStatusChangedEvent(object source, ProcessStatusEventArgs rea)
		{
			if(!rea.IsRunning)
			{
				b_IsAlive = false;
				if(theProcess!=null)
				{
					try
					{
						try
						{
							theProcess.Kill();
						}
						catch
						{
						}
					}
					finally
					{
						theProcess = null;
					}
				}
			}
			if(ProcessStatusChangedEvent!=null)
			{
				this.ProcessStatusChangedEvent(source, rea);
			}
		}

		#endregion


		#region IsAlive
		public bool IsAlive
		{
			get
			{
				return b_IsAlive;
			}
		}
		#endregion

		#region Dispose()
		public void Dispose()
		{
			if(theProcess!=null)
			{
				ShutDown();
			}
		}
		#endregion

		#region Process StartUpProcess
		protected Process StartUpProcess(string exe, string cmd)
		{
			try
			{
				if(!b_IsAlive)
				{
					theProcess = Process.Start(exe, cmd);
					PID = theProcess.Id;
					b_IsAlive = true;
				}
				// April 12, 05
				OnProcessStatusChangedEvent(this, new ProcessStatusEventArgs( theProcess, true) );
				return theProcess;
			}
			catch(Exception ex)
			{
				OnProcessStatusChangedEvent(this, new ProcessStatusEventArgs( theProcess, false) );
				Console.Write("CallbackMNethod.InitRemoting", "Cannot start process: "+exe+"\r\n\r\n"+ex.Message, 
					System.Diagnostics.EventLogEntryType.Error, 0);
				//MessageBox.Show ( "Cannot start process: "+exe+"\r\n\r\n"+ex.Message);
				return null;
			}
		}
		#endregion

		#region Initialize()
		public void Initialize(string theApp2Watch)
		{
			theProcess = FindProcess();
			if(theProcess==null)
			{
				theProcess = StartUp(theApp2Watch);
				if(theProcess==null)
					throw new Exception();
			}
		}
		#endregion

		
		public AppWrapper()
		{
			try
			{
				string AppPath = System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location );
				//SAMShareIniFile = new Utils.IniFile(AppPath+@"\SAMShare.ini");
			}
			catch(Exception ex)
			{
				Console.Write("IPCParent", "Constructoe: "+ex.Message, 
					System.Diagnostics.EventLogEntryType.Error, 0);
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Canada Canada
Software development experience since 1993

Skills
- Programming Languages: C# .NET, Delphi, C++, Java and VB
- Development Methodologies (SDLC): RUP, Scrum and XP
- Database: SQL server, Oracle, Apollo database and MS Access.

Educations & Certificates
- Microsoft® Certified Professional (MCP)
- Sun® Certified Java2 Programmer
- B.S. in computer science

Comments and Discussions