Simple Interprocess Communication





5.00/5 (2 votes)
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;
}
}
}
}