Click here to Skip to main content
15,893,814 members
Articles / Mobile Apps

A simple solution to see the inside of your code

Rate me:
Please Sign up or sign in to vote.
4.69/5 (13 votes)
25 May 2006CPOL2 min read 54.9K   906   43  
A simple solution to see the inside of your code.
//==================================================================================================
//
//	AUTHOR		:	George Lang
//
//	COPYRIGHT	:	(C) 2005, Easy Software Integration, Romania ( www.esi-production.ro )
//
//	HISTORY		:
//
//		V 1.00.00	14-09-2005	    created by George Lang
//
//--------------------------------------------------------------------------------------------------
//	Revision Management History	
//--------------------------------------------------------------------------------------------------
//	
//  $Revision::                      $Date::                                                      	
//
//   $Archive::                                                                                    	
//    $Author::                                                                                    
//
//==================================================================================================
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;


namespace MyTracer
{
	/// <summary>
	/// PipeServer implement server functionality.
	/// <br></br>
	/// <br></br>
	/// <br></br>
	/// <para><b>Commands:</b></para>
	/// <br></br>
	/// <list>
	/// <li>Start tracer</li>
	/// <li>Stop tracer</li>
	/// <li>Clear messages</li>
	/// </list>
	/// <br></br>
	/// <br></br>
	/// <br></br>
	/// <para><b>Application show various information like:</b></para>
	/// <br></br>
	/// <list>
	/// <li>Type		- error, warning, information, service(reserved), unknown</li>
	/// <li>DateTime	- message time</li>
	/// <li>Application - application who generate the message</li>
	/// <li>Source		- Assembly.Class.Method who generate the message</li>
	/// <li>Message		- message text</li>
	/// </list>
	/// <br></br>
	/// <br></br>
	/// <br></br>
	/// <para><b>A demo version of this application look like below:</b></para>
	/// <img src="d:\demo.bmp"></img>
	/// </summary>
	public class PipeServer : Server
	{
		#region Const
		
		const int BUFFER_SIZE	= 1024;
		const int PIPES_NO		= 10;
		const string PipeName	= @"\\.\pipe\esiLogger";
		
		#endregion

		#region Members

		Thread[]		_PipeThread = new Thread[PIPES_NO];
		IntPtr[]		_Handle;
		int				_PipeNo;
		
		AutoResetEvent	_syncEvent;
		
		
		#endregion

		#region Constructors

		public PipeServer()
		{
			_serverType = Pipe;
			_PipeNo = 0;

			_syncEvent = new AutoResetEvent(false);
			_Handle = new IntPtr[PIPES_NO];
			
			for( int i=0; i<PIPES_NO; i++)
				_Handle[i] = IntPtr.Zero;
		}


		#endregion

		#region Methods

		/// <summary>
		/// Start server
		/// </summary>
		public void Start()
		{
			RunHandler runHandler = new RunHandler(Run);
			AsyncCallback asyncRun = new AsyncCallback( ConnectResult );
			runHandler.BeginInvoke( asyncRun, 12 );
		}


		/// <summary>
		/// Server main loop
		/// </summary>
		/// <returns>return false if application can't create or connect to a named pipe</returns>
		bool Run()
		{
			while( !_keepWorking.WaitOne( 0, true) )
			{
				for(int i=0; i<PIPES_NO; i++)
					if (_Handle[i] == IntPtr.Zero)
					{
						_PipeNo = i;
						break;
					}
			
				_Handle[_PipeNo] = W32API.CreateNamedPipe(
					PipeName,
					W32API.PIPE_ACCESS_DUPLEX,			// read/write access 
					W32API.PIPE_TYPE_MESSAGE |			// message type pipe 
					W32API.PIPE_READMODE_MESSAGE |		// message-read mode 
					W32API.PIPE_WAIT,					// blocking mode 
					W32API.PIPE_UNLIMITED_INSTANCES,	// max. instances  
					BUFFER_SIZE,						// output buffer size 
					BUFFER_SIZE,						// input buffer size 
					W32API.NMPWAIT_USE_DEFAULT_WAIT,	// client time-out 
					IntPtr.Zero);						// default security attribute 

				if ( _Handle[_PipeNo].ToInt32() == W32API.INVALID_HANDLE_VALUE )
				{
					FireError("Create pipe failed!");
					return false;
				}

				if ( !W32API.ConnectNamedPipe( _Handle[_PipeNo], null) )
				{
					FireError("Failed to connect to pipe!");
					return false;
				}

				_PipeThread[_PipeNo] = new Thread( new ThreadStart(Read) );
				_PipeThread[_PipeNo].Priority = ThreadPriority.Highest;
				_PipeThread[_PipeNo].Start();
				
				_syncEvent.WaitOne();
			}

			return true;
		}


		void ConnectResult(IAsyncResult ar)
		{
		
		}


		/// <summary>
		/// Read from pipe
		/// </summary>
		void Read()
		{
			byte[] byteRes = new byte[BUFFER_SIZE];
			uint dwRead = 0;

			int PipeNo = _PipeNo;
			_syncEvent.Set();
			
			while( !_keepWorking.WaitOne( 0, true) )
			{
				W32API.ReadFile( _Handle[PipeNo], byteRes, BUFFER_SIZE, ref dwRead, 0 );
				
				if (dwRead==0)
					break;
				
				FireMessage( byteRes );
				Array.Clear( byteRes, 0, byteRes.Length);
			}
			
			W32API.FlushFileBuffers( _Handle[PipeNo] ); 
			W32API.DisconnectNamedPipe( _Handle[PipeNo] );
			W32API.CloseHandle( _Handle[PipeNo] ); 
			_Handle[PipeNo] = IntPtr.Zero;
		}


		/// <summary>
		/// Stop server
		/// </summary>
		public void Stop()
		{
			if (_keepWorking != null)
			{
				_keepWorking.Set();
			}
		}

		#endregion
	}
}

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
Romania Romania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions