Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How To Make Hooks on Serial Ports in C#

0.00/5 (No votes)
17 Sep 2009 6  
An article on creating serial port hooks in C#

Introduction

This C# console program illustrates how to use serial port hooks in C#, in a sense. This is because there’s really no readily available API which provides hooking the serial port unlike windows messages, keyboard, and mouse, etc, in which you can use SetWindowsHookEx API.

Background

So you popped up your favorite inet browser, opened your favorite search engine and type “How do I make hook on serial port in C#?”.

Then your search engine begins to search the vast WWW. Voila!

Unless I’m wrong as I may not have searched the inet long enough to dig one, your search results are not exactly the one’s you’re expecting.

So here’s C# console program that at least illustrates the concept in a very simple example. Firstly, we create a WIN32 serial library (see documentation WIN32 Serial Module.chm ) which provides serial hook interfaces. The serial library takes advantage of the overlap option providing asynchronous I/O thus making the hooks a possibility. Then we import the serial library methods in C#. That’s it.

Using the code

If your interest is to be able to use hardware flow control, this is not the right post for you as the serial library does not provide that functionality in this example. However, with a little patience for a small work, you can extend the existing library to do the job.

So this is an example that provides transparent data transfer from a terminal to the application layer and vice-versa. Yet this does not obstruct you to implement your own messaging protocol (i.e. at its simplest STX + <Data> +STX + LRC).

Just like any other non-static classes, you just need to create an instance of class CommsSerial to use it on your program as shown below:

Note that this console program requires the serial port number to be passed as a program argument.

namespace UsingWIN32SerialHooksInCSharp
{
    class SerialProgram
    {
        private CommsSerial comSerial;        

        private void SerialSimulation(ushort port)
        {
            try
            {
              comSerial = new CommsSerial();

                comSerial.SerialReceptionEvent += 
			delegate(object obj, ComEventArgs comEventArgs)
                {
                    Console.WriteLine("\n---Data available notification----");
                    Console.WriteLine("{0} byte(s) successfully read.", 
						comEventArgs.Length);
                    Console.WriteLine("Data: {0}", comEventArgs.ToString());

                    //
                    // Write data to serial.
                    // In real applications, this could be the response after analyzing
                    // the received data.
                    //
                    byte[] dataToWrite = new byte[] { 0x02, (byte)'T', 
				(byte)'E', (byte)'S', (byte)'T', 0x03 };
                    Console.WriteLine("\nWriting {0} byte(s) of data. \nData: {1}",
                                        dataToWrite.Length,
                                        Conversion.BytesToAsciiHex
					(dataToWrite,dataToWrite.Length)
                                        );
                    //write data
                    comSerial.Write(dataToWrite, (uint)dataToWrite.Length );
                };

                comSerial.SerialTransmitEvent += 
			delegate(object obj, ComEventArgs comEventArgs)
                {
                    Console.WriteLine("\n---Write finished notification----");
                    Console.WriteLine("{0} byte(s) successfully written.", 
							comEventArgs.Length);
                };

                try
                {
                    Console.Write("\nOpening serial COM port...");

                    //Open the serial port
                    comSerial.Open(port,
                                CommsSerial.DataSize.EIGHT_BITS,
                                CommsSerial.ParityBit.NOPARITY,
                                CommsSerial.StopBit.ONESTOPBIT,
                                CommsSerial.BaudRate.CBR_115200
                                );

                    Console.WriteLine("OK!");

                    Console.Write("\nInstalling hooks...");
                    //Install the hooks
                    comSerial.InstallHooks();
                    Console.WriteLine("OK!");

                    do
                    {
                        Console.WriteLine("\nSerial monitor listening...\n");

                        //
                        // Do something
                        //
                        // i.e. maybe until stop button is pressed.
                        // 

                        //Simulate active to inactivated state
                        //Active until 25 seconds timeout expires.                        
                        Thread.Sleep(20000);

                        Console.WriteLine("Closing serial monitor...");

                    } while (false);

                    //Uninstall hooks
                    comSerial.UninstallHooks();

                    //
                    comSerial.Close();
                    Console.WriteLine("Monitor closed.");
                }
                catch (SerialManagedException)
                {
                    //Re-throw exceptions
                    throw;
                }
                catch (Exception)
                {
                    //Re-throw exceptions
                    throw;
                }
            }
            catch (SerialManagedException ex)
            {
                Console.WriteLine("A serial exception occurred.");
                Console.WriteLine(ex.Message);
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine("An argument exception occurred.");
                Console.WriteLine(ex.Message);
            }
            catch(Exception ex)
            {
                Console.WriteLine("Unknown exception occurred.");
                Console.WriteLine(ex.Message);
            }
        }

        static void Main(string[] args)
        {
            ushort port;

            if (args.Length==0)
            {
                Console.WriteLine("\nError: No program argument provided!");
                Console.WriteLine("\nUsage: {0} [serial port]", 
                                    Path.GetFileName
				(Process.GetCurrentProcess().MainModule.FileName)
                                    );
                Console.WriteLine("\n");
                Console.ReadKey();
                return;
            }

            port = Convert.ToUInt16(args[0]);
            if ( port == 0 || port > 15)
            {
                //Default port
                port = 1;
            }            

            SerialProgram serialProgram = new SerialProgram();
            //Perform serial simulation
            serialProgram.SerialSimulation(port);

            //Simulation has ended.
            Console.WriteLine("\nSimulation finished.");
            Console.WriteLine("<press>");
            Console.ReadKey();        
        }
    }
}

History

  • Initial code version 1.0

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here