Eclipsed4utoo's Blog
Not Your Ordinary Programmer

C# – Completely Managed Inter-process Communication

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: , , , ,

4 Responses to “C# – Completely Managed Inter-process Communication” »

  1. Ikonmx Says:

    In which part of dream in code is this code posted? Would like to see the full code. Do this code work like a message window?

    Best regards.

  2. Ryan Alford Says:

    The full code isn’t posted there. For the communication between the applications, this is all of the code.

    I am unfamiliar with a “message window” so I wouldn’t know if they are similar.

  3. Dennis Says:

    Wouldn’t it be better to have the background-application act as the pipe-server, waiting for connections (using PipeDirection.In) and have the client activly create the connection?

    In your example, I get the feeling that if the service is not running (for some reason), the application will wait forever before it can continue.

  4. Ryan Alford Says:

    Yes, it could be switched. If the background app was to be deemed the “Server”, then the “server” code would have to be run on another thread, just as the “client” code is ran.

    Though it could cause a pause in the main app if the roles were switched. The “Connect” method that I run from the background app will pause the thread until it gets a connection to the “server”, or until the timeout has expired. I set it to 10 seconds, which would not be a good value for a main UI thread to pause for 10 seconds. However, in the background app, that 10 seconds doesn’t matter because the user never sees it.

    As for the service not running, I have code that determines if it’s running or not, and starts it if it’s not running.

    So I would say that either way, it should work fine.

Leave a Comment