65.9K
CodeProject is changing. Read more.
Home

Simple Interprocess Communication

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2 votes)

Mar 29, 2011

CPOL
viewsIcon

15750

I use this code so that when another instance of my application is started, I can send the command line parameters to it, and it can queue the request. In the main application I call Remote.Start() and on startup I check if another instance exists and if so I call Remote.Send("command line") see Run Only One Copy Of Application[^] for details.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Pipes;
using System.Threading;

//From http://bartdesmet.net/blogs/bart/archive/2007/04/12/getting-started-with-named-pipes.aspx
namespace Application
{
    class Remote
    {
        const string CHANNEL = "ApplicationName";
        const int TIMEOUT = 30000;  //30 seconds if we start an application
        const int EXIT_TIME = 1000; //1 second if we are exiting

        static NamedPipeServerStream server;
        static Thread thread;
        static StreamReader reader;
        static List<string> messages;
        static bool waiting;
        static bool abort;


        public static void Send(string args)
        {
            using (NamedPipeClientStream client = new NamedPipeClientStream(".", CHANNEL, PipeDirection.InOut))
            {
                try
                {
                    client.Connect(TIMEOUT);
                }
                catch (Exception)
                {
                    return;
                }

                using (StreamWriter writer = new StreamWriter(client))
                {
                    writer.WriteLine(args);
                    writer.Flush();
                }
            }
        }

        public static void Start()
        {
            server = new NamedPipeServerStream(CHANNEL, PipeDirection.InOut);
            thread = new Thread(WaitForMessages);
            messages = new List<string>(10);
            thread.Start();
        }

        private static void WaitForMessages()
        {
            while (!abort)
            {
                try
                {
                    server.WaitForConnection();
                    if (abort)
                    {
                        break;
                    }
                    reader = new StreamReader(server);
                    while (server.IsConnected)
                    {
                        if (abort)
                        {
                            break;
                        }
                        string line = reader.ReadLine();
                        lock (messages)
                        {
                            messages.Add(line);
                            //Do something in your code with line
                            Console.WriteLine(line);
                        }
                        waiting = true;
                    }
                    reader.Dispose();
                    reader = null;
                    server.Dispose();
                    server = null;
                    if (abort)
                    {
                        break;
                    }
                    server = new NamedPipeServerStream(CHANNEL, PipeDirection.InOut);
                }
                catch (Exception)
                {
                }
            }
        }

        public static bool MessageWaiting
        {
            get
            {
                return waiting;
            }
        }

        public static string GetMessage()
        {
            string ret;
            lock (messages)
            {
                ret = messages[0];
                messages.RemoveAt(0);
                if (messages.Count == 0)
                {
                    waiting = false;
                }
            }
            return ret;
        }

        public static void End()
        {
            abort = true;
            if (server != null)
            {
                if (server.IsConnected)
                {
                    server.Disconnect();
                }
                else
                {
                    try
                    {
                        //Make sure it connects in order to get it to time out
                        using (NamedPipeClientStream client = new NamedPipeClientStream(".", CHANNEL, PipeDirection.InOut))
                        {
                            client.Connect(EXIT_TIME);
                        }
                    }
                    catch (Exception)
                    {
                    }
                }

                server.Dispose();
                server = null;
            }
            thread = null;
            if (reader != null)
            {
                reader.Dispose();
                reader = null;
            }
        }
    }
}