这是我写的一个小助手。
使用方法:
var pipeListener = new NamedPipeListener<String>()
pipeListener.MessageReceived += (sender, e) => MessageBox.Show(e.Message)
pipeListener.Error += (sender, e) => MessageBox.Show("Error ({0}): {1}", e.ErrorType, e.Exception.Message)
pipeListener.Start()
来自另一个进程:
NamedPipeListener<String>.SendMessage("Howdy howdy howdy");
注意,它使用PipeListener的全名作为管道的默认名称。如果您需要更细致的控制,可以使用接受管道名称的构造函数重载。
以下是该类:
using System;
using System.IO.Pipes;
using System.Runtime.Serialization.Formatters.Binary;
namespace FunWithNamedPipes
{
public class NamedPipeListenerMessageReceivedEventArgs<TMessage> : EventArgs
{
public NamedPipeListenerMessageReceivedEventArgs(TMessage message)
{
this.Message = message;
}
public TMessage Message { get; private set; }
}
public class NamedPipeListenerErrorEventArgs : EventArgs
{
public NamedPipeListenerErrorEventArgs(NamedPipeListenerErrorType errorType, Exception ex)
{
this.ErrorType = errorType;
this.Exception = ex;
}
public NamedPipeListenerErrorType ErrorType { get; private set; }
public Exception Exception { get; private set; }
}
public delegate void NamedPipeMessageReceivedHandler<TMessage>(Object sender, NamedPipeListenerMessageReceivedEventArgs<TMessage> e);
public delegate void NamedPipeMessageErrorHandler(Object sender, NamedPipeListenerErrorEventArgs e);
public enum NamedPipeListenerErrorType : byte
{
BeginWaitForConnection = 1,
EndWaitForConnection = 2,
DeserializeMessage = 3,
CloseAndDisposePipe = 4,
NotifyMessageReceived = 5
}
public class NamedPipeListener<TMessage> : IDisposable
{
public event NamedPipeMessageReceivedHandler<TMessage> MessageReceived;
public event NamedPipeMessageErrorHandler Error;
static readonly String DEFAULT_PIPENAME = typeof(NamedPipeListener<TMessage>).FullName;
static readonly BinaryFormatter formatter = new BinaryFormatter();
NamedPipeServerStream pipeServer;
public NamedPipeListener(String pipeName)
{
this.PipeName = pipeName;
}
public NamedPipeListener()
: this(DEFAULT_PIPENAME) { }
public String PipeName { get; private set; }
internal void Start()
{
if (pipeServer == null) pipeServer = new NamedPipeServerStream(DEFAULT_PIPENAME, PipeDirection.In, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
try { pipeServer.BeginWaitForConnection(new AsyncCallback(PipeConnectionCallback), null); }
catch (Exception ex) { this.OnError(NamedPipeListenerErrorType.BeginWaitForConnection, ex); }
}
private void PipeConnectionCallback(IAsyncResult result)
{
try
{
pipeServer.EndWaitForConnection(result);
}
catch (Exception ex)
{
this.OnError(NamedPipeListenerErrorType.EndWaitForConnection, ex);
return;
}
TMessage message;
try
{
message = (TMessage)formatter.Deserialize(pipeServer);
}
catch (Exception ex)
{
this.OnError(NamedPipeListenerErrorType.DeserializeMessage, ex);
return;
}
try
{
this.OnMessageReceived(new NamedPipeListenerMessageReceivedEventArgs<TMessage>(message));
}
catch (Exception ex)
{
this.OnError(NamedPipeListenerErrorType.NotifyMessageReceived, ex);
return;
}
if (this.End())
{
this.Start();
}
}
internal Boolean End()
{
try
{
pipeServer.Close();
pipeServer.Dispose();
pipeServer = null;
return true;
}
catch (Exception ex)
{
this.OnError(NamedPipeListenerErrorType.CloseAndDisposePipe, ex);
return false;
}
}
private void OnMessageReceived(TMessage message)
{
this.OnMessageReceived(new NamedPipeListenerMessageReceivedEventArgs<TMessage>(message));
}
protected virtual void OnMessageReceived(NamedPipeListenerMessageReceivedEventArgs<TMessage> e)
{
if (this.MessageReceived != null)
{
this.MessageReceived(this, e);
}
}
private void OnError(NamedPipeListenerErrorType errorType, Exception ex)
{
this.OnError(new NamedPipeListenerErrorEventArgs(errorType, ex));
}
protected virtual void OnError(NamedPipeListenerErrorEventArgs e)
{
if (this.Error != null)
{
this.Error(this, e);
}
}
void IDisposable.Dispose()
{
if(pipeServer != null)
{
try { pipeServer.Disconnect(); }
catch { }
try { pipeServer.Close(); }
catch { }
try { pipeServer.Dispose(); }
catch { }
}
}
public static void SendMessage(TMessage message)
{
NamedPipeListener<TMessage>.SendMessage(DEFAULT_PIPENAME, message);
}
public static void SendMessage(String pipeName, TMessage message)
{
using (var pipeClient = new NamedPipeClientStream(".", DEFAULT_PIPENAME, PipeDirection.Out, PipeOptions.None))
{
pipeClient.Connect();
formatter.Serialize(pipeClient, message);
pipeClient.Flush();
pipeClient.WaitForPipeDrain();
pipeClient.Close();
}
}
}
}