Skip to content

Instantly share code, notes, and snippets.

@Suplanus
Last active August 28, 2019 06:53
Show Gist options
  • Save Suplanus/f652a15a55bff64b6ccb33836041f8bb to your computer and use it in GitHub Desktop.
Save Suplanus/f652a15a55bff64b6ccb33836041f8bb to your computer and use it in GitHub Desktop.
NamedPipeServerStream & NamedPipeClientStream InOut async: https://suplanus.de/namedpipestream-inout-async/
// Client
var pipeClient = new PipeBidirectional(PipeType.Client);
pipeClient.PipeMessage += PipeServerOnPipeMessage;
pipeClient.Start("MyPipe");
pipeClient.ListenAsync();
pipeClient.WriteAsync("Hello from Client");
private static void PipeServerOnPipeMessage(string args)
{
// Do stuff
}
// Server
var pipeServer = new PipeBidirectional(PipeType.Server);
pipeServer.PipeMessage += PipeServerOnPipeMessage;
pipeServer.Start("MyPipe");
pipeServer.ListenAsync();
pipeServer.WriteAsync("Hello from Server");
private void PipeServerOnPipeMessage(string args)
{
// Do stuff
}
// Model
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Linq;
namespace Suplanus.Pipes
{
public class PipeBidirectional : IDisposable
{
public int MaxNumberOfServerInstances { get; set; } = 1;
public int InBufferSize { get; set; } = 4096;
public int OutBufferSize { get; set; } = 4096;
public event DelegateMessage PipeMessage;
private readonly PipeType _pipeType;
private NamedPipeServerStream _serverPipe;
private NamedPipeClientStream _clientPipe;
private Process _clientProcess;
private StreamWriter _streamWriter;
private StreamReader _streamReader;
public PipeBidirectional(PipeType pipeType)
{
_pipeType = pipeType;
}
public void Start(string pipeName, string clientProcessPath = null)
{
switch (_pipeType)
{
case PipeType.Server:
_serverPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut,
MaxNumberOfServerInstances,
PipeTransmissionMode.Message, PipeOptions.Asynchronous, InBufferSize,
OutBufferSize);
// Start client process
if (!string.IsNullOrEmpty(clientProcessPath))
{
_clientProcess = Process.GetProcesses()
.FirstOrDefault(obj => clientProcessPath.Contains(obj.ProcessName) &&
obj.MainModule != null &&
obj.MainModule.FileName.Equals(clientProcessPath));
if (_clientProcess == null)
{
_clientProcess = Process.Start(new ProcessStartInfo
{
CreateNoWindow = true,
FileName = clientProcessPath,
UseShellExecute = false,
});
}
}
// Start server
_serverPipe.WaitForConnection();
_streamWriter = new StreamWriter(_serverPipe);
_streamWriter.AutoFlush = true;
_streamReader = new StreamReader(_serverPipe);
break;
// Start client
case PipeType.Client:
_clientPipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut,
PipeOptions.Asynchronous);
_clientPipe.Connect();
_streamWriter = new StreamWriter(_clientPipe);
_streamWriter.AutoFlush = true;
_streamReader = new StreamReader(_clientPipe);
break;
}
}
public async void ListenAsync()
{
do
{
if (_streamReader != null)
{
string line = await _streamReader.ReadLineAsync();
if (!string.IsNullOrEmpty(line))
{
PipeMessage?.Invoke(line);
}
}
}
while (true);
// ReSharper disable once FunctionNeverReturns
}
public async void WriteAsync(string message)
{
await _streamWriter.WriteLineAsync(message);
}
public void Dispose()
{
_streamWriter?.Dispose();
_streamReader?.Dispose();
if (_serverPipe != null && _serverPipe.IsConnected)
{
_serverPipe?.Disconnect();
}
_serverPipe?.Dispose();
_clientPipe?.Dispose();
_clientProcess?.Kill();
_clientProcess?.Dispose();
}
}
public delegate void DelegateMessage(string args);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment