Posts Tagged ‘NamedPipeClientStream’

.Net C# – Completely Managed Inter-process Communication

9 Comments

This post is going to deal with a way to accomplish IPC, Inter-Process Communication.  Starting with .Net 3.5, Microsoft made this very, very easy for .Net developers.

I was creating an application that would run without user interaction.  It would be running minimized and not showing in the taskbar, though it would have a NotifyIcon so it’s UI could be viewed.

The purpose of this application was to monitor a serial port for incoming badge scans.  So it would constantly have a connection open to the serial port.  The problem arose because the main application that the users would be using also needed to receive badge scans.   So I have the main application that needed to accept badge scans at specific points in the application, but I also needed the background application to continuously monitor the serial port.

So I needed someway for the main application to tell the background application that it needed the serial port.  Then once the main application was done with the serial port, it needed to let the background application know so that it could start monitoring the serial port again.

So after posting at Dream.In.Code.net, I was given the suggestion of using the NamedPipeServerStream and the NamedPipeClientStream.

Main application

 public static void SendStreamData(string command)
{
    try
    {
         using (NamedPipeServerStream pipe = new NamedPipeServerStream("myPipe", PipeDirection.Out))
         {
              // creates the named pipe and waits for a client to connect
              pipe.WaitForConnection();

              // after a connection has been established, write to the stream
              using (StreamWriter sw = new StreamWriter(pipe))
              {
                   sw.AutoFlush = true;
                   sw.WriteLine(command);
              }
         }

         Thread.Sleep(1000);
    }
    catch (Exception ex)
    {
         MessageBox.Show("ERROR: " + ex.Message);
    }
}

In the previous code, the main application is considered the “Server”.  When it needs to serial port, it creates the named pipe, and waits for a client to connect.  Once a client connects, it writes to the stream.

So next, we have the background application’s code.  The background application is considered the “Client”.

Background app’s code

private void GetStreamData()
{
    try
    {
         using (NamedPipeClientStream pipe = new NamedPipeClientStream(".", "myPipe", PipeDirection.In))
         {
             // Connects to a named pipe that has already been created
             // 10 second timeout period
             pipe.Connect(10000);

             // once connected, reads from the stream
             using (StreamReader sr = new StreamReader(pipe))
             {
                 string data;

                 while ((data = sr.ReadLine()) != null)
                 {
                     if (data == "I CAN HAZ PORT?")
                     {
                         // Main application signals that it needs the serial port
                         CloseBadgeReader();
                     }
                     else
                     {
                         // Main application signals it is done with serial port
                         CreateBadgeReader();
                     }
                 }
             }
          }
    }
    catch (Exception ex)
    {
        MessageBox.Show("ERROR: " + ex.Message);
    }
}

And that’s it.  The background application will continuously try to connect to the named pipe.  The Connect method will continue to try to connect if the named pipe isn’t found, until the timeout period has been expired.  If it get’s a certain command from the named pipe, it will close it’s connection to the serial port.  If it get’s anything else, it will reconnect to the serial port.

Tags: , , , ,