AaTurpin.NamedPipes
1.0.0
The owner has unlisted this package.
This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package AaTurpin.NamedPipes --version 1.0.0
NuGet\Install-Package AaTurpin.NamedPipes -Version 1.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AaTurpin.NamedPipes" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AaTurpin.NamedPipes" Version="1.0.0" />
<PackageReference Include="AaTurpin.NamedPipes" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AaTurpin.NamedPipes --version 1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: AaTurpin.NamedPipes, 1.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AaTurpin.NamedPipes@1.0.0
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AaTurpin.NamedPipes&version=1.0.0
#tool nuget:?package=AaTurpin.NamedPipes&version=1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
AaTurpin.NamedPipes
A lightweight, robust .NET library for inter-process communication using Windows named pipes. The library provides an easy-to-use API for creating named pipe servers and clients with support for logging, automatic reconnection, and proper resource management.
Features
- Easy to use API - Simple methods for creating servers and clients
- Robust connection handling - Automatic reconnection capabilities
- Thread-safe operations - All operations are thread-safe and can be used in multi-threaded applications
- Comprehensive logging - Integrates with RunLog for detailed logging
- Proper resource management - All resources are properly disposed when no longer needed
- Compatible with .NET Framework 4.7.2 and above
Installation
NuGet
PM> Install-Package AaTurpin.NamedPipes
Usage
Basic Usage
Create a Named Pipe Server
using AaTurpin.NamedPipes;
using RunLog;
// Set up logging
var logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
Log.Logger = logger;
// Create a command handler function
string CommandHandler(string command)
{
Console.WriteLine($"Received command: {command}");
return $"Command '{command}' processed successfully!";
}
// Create and start the server
using (var server = new NamedPipeServer("MyPipe", CommandHandler))
{
server.Start();
Console.WriteLine("Server started. Press Enter to stop...");
Console.ReadLine();
server.Stop();
}
Create a Named Pipe Client
using AaTurpin.NamedPipes;
using RunLog;
// Set up logging
var logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
Log.Logger = logger;
// Create and connect the client
using (var client = new NamedPipeClient("MyPipe", "."))
{
if (client.Connect())
{
string response = client.SendCommand("Hello Server!");
Console.WriteLine($"Server responded: {response}");
}
else
{
Console.WriteLine("Failed to connect to server.");
}
}
Advanced Usage
Asynchronous Client with Automatic Reconnection
using AaTurpin.NamedPipes;
using RunLog;
using System;
using System.Threading;
// Set up logging
var logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
Log.Logger = logger;
// Create a response handler function
void ResponseHandler(string response)
{
Console.WriteLine($"Received response: {response}");
}
// Create and connect the client with auto-reconnect
using (var client = new NamedPipeClient(
pipeName: "MyPipe",
serverName: ".",
responseHandler: ResponseHandler,
connectionTimeout: 5000,
reconnectDelay: 1000,
maxRetries: 3))
{
if (client.Connect(autoReconnect: true))
{
// With a response handler, SendCommand returns immediately
// Responses will be delivered to the ResponseHandler
client.SendCommand("Hello Server!");
// Keep sending commands periodically
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
if (client.IsConnected)
{
client.SendCommand($"Command #{i}");
}
}
}
else
{
Console.WriteLine("Failed to connect to server.");
}
}
Custom Server Configuration with Logging
using AaTurpin.NamedPipes;
using RunLog;
using System;
using System.IO;
using System.Threading;
// Set up advanced logging
var logsDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
Directory.CreateDirectory(logsDir);
var logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(LogLevel.Information)
.WriteTo.File(
path: Path.Combine(logsDir, "pipe-server-.log"),
restrictedToMinimumLevel: LogLevel.Debug,
rollingInterval: RollingInterval.Day,
fileSizeLimitBytes: 10 * 1024 * 1024,
retainedFileCountLimit: 7,
enableBuffering: true,
bufferSize: 100,
backgroundThread: true)
.CreateLogger();
Log.Logger = logger;
NamedPipeServer.SetLogger(logger);
// Create command handler with logging
string CommandHandler(string command)
{
Log.Information("Processing command: {Command}", command);
try
{
// Process command...
Thread.Sleep(100); // Simulate work
string result = $"Processed: {command} at {DateTime.Now}";
Log.Information("Command processed successfully: {Result}", result);
return result;
}
catch (Exception ex)
{
Log.Error(ex, "Error processing command: {Command}", command);
return $"Error: {ex.Message}";
}
}
// Create and start server
using (var server = new NamedPipeServer("MyAdvancedPipe", CommandHandler))
{
server.Start();
Log.Information("Server started. Press Enter to stop...");
Console.ReadLine();
server.Stop();
Log.CloseAndFlush();
}
Example Applications
Simple Chat Application
Server (Host)
using AaTurpin.NamedPipes;
using RunLog;
using System;
using System.Collections.Generic;
class ChatServer
{
private NamedPipeServer server;
private Dictionary<string, NamedPipeClient> clients = new Dictionary<string, NamedPipeClient>();
public ChatServer()
{
// Set up logging
var logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
Log.Logger = logger;
// Create server
server = new NamedPipeServer("ChatPipe", HandleMessage);
}
public void Start()
{
server.Start();
Console.WriteLine("Chat server started. Type 'exit' to quit.");
while (true)
{
string input = Console.ReadLine();
if (input.ToLower() == "exit")
break;
// Host message
BroadcastMessage("Host", input);
}
}
private string HandleMessage(string message)
{
try
{
// Parse incoming message format: "Name:Message"
int colonIndex = message.IndexOf(':');
if (colonIndex <= 0) return "ERROR: Invalid message format";
string sender = message.Substring(0, colonIndex);
string content = message.Substring(colonIndex + 1);
Console.WriteLine($"{sender}: {content}");
// Broadcast message to all clients
BroadcastMessage(sender, content);
return "OK";
}
catch (Exception ex)
{
return $"ERROR: {ex.Message}";
}
}
private void BroadcastMessage(string sender, string message)
{
// In this simplified example, we're just logging the messages
// In a real application, you would send the messages to all connected clients
Console.WriteLine($"BROADCAST: {sender}: {message}");
}
public void Stop()
{
server.Stop();
}
public void Dispose()
{
server.Dispose();
}
static void Main(string[] args)
{
using (var chat = new ChatServer())
{
chat.Start();
chat.Stop();
}
}
}
Client
using AaTurpin.NamedPipes;
using RunLog;
using System;
using System.Threading;
class ChatClient
{
private NamedPipeClient client;
private string userName;
public ChatClient(string userName)
{
this.userName = userName;
// Set up logging
var logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
Log.Logger = logger;
// Create client with response handler
client = new NamedPipeClient(
pipeName: "ChatPipe",
serverName: ".",
responseHandler: HandleResponse,
maxRetries: 5);
}
public void Start()
{
if (client.Connect(autoReconnect: true))
{
Console.WriteLine("Connected to chat server. Type your messages (or 'exit' to quit).");
while (true)
{
string input = Console.ReadLine();
if (input.ToLower() == "exit")
break;
if (client.IsConnected)
{
client.SendCommand($"{userName}:{input}");
}
else
{
Console.WriteLine("Disconnected from server. Attempting to reconnect...");
Thread.Sleep(1000);
}
}
}
else
{
Console.WriteLine("Failed to connect to chat server.");
}
}
private void HandleResponse(string response)
{
if (response.StartsWith("ERROR:"))
{
Console.WriteLine($"Error: {response.Substring(6)}");
}
}
public void Stop()
{
client.Disconnect();
}
public void Dispose()
{
client.Dispose();
}
static void Main(string[] args)
{
Console.Write("Enter your name: ");
string name = Console.ReadLine();
using (var chat = new ChatClient(name))
{
chat.Start();
chat.Stop();
}
}
}
Monitoring Service Example
This example demonstrates using named pipes for a monitoring service that collects system information from multiple clients.
Monitor Server
using AaTurpin.NamedPipes;
using RunLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading;
class MonitorServer
{
private NamedPipeServer server;
private Dictionary<string, SystemInfo> clientStatus = new Dictionary<string, SystemInfo>();
private Timer displayTimer;
public class SystemInfo
{
public string ClientName { get; set; }
public double CpuUsage { get; set; }
public double MemoryUsageMB { get; set; }
public long DiskSpaceMB { get; set; }
public DateTime LastUpdated { get; set; }
}
public MonitorServer()
{
// Setup logging
var logsDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
Directory.CreateDirectory(logsDir);
var logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File(Path.Combine(logsDir, "monitor-server-.log"),
rollingInterval: RollingInterval.Day)
.CreateLogger();
Log.Logger = logger;
// Create server
server = new NamedPipeServer("MonitorPipe", HandleClientUpdate);
// Set up timer to display status every 5 seconds
displayTimer = new Timer(DisplayStatus, null, 5000, 5000);
}
public void Start()
{
server.Start();
Console.WriteLine("Monitor server started. Press Enter to quit.");
Console.ReadLine();
}
private string HandleClientUpdate(string update)
{
try
{
// Parse the JSON update
var systemInfo = JsonSerializer.Deserialize<SystemInfo>(update);
systemInfo.LastUpdated = DateTime.Now;
// Update the client status
lock (clientStatus)
{
clientStatus[systemInfo.ClientName] = systemInfo;
}
return "OK";
}
catch (Exception ex)
{
Log.Error(ex, "Error processing client update");
return $"ERROR: {ex.Message}";
}
}
private void DisplayStatus(object state)
{
Console.Clear();
Console.WriteLine("=== System Monitor ===");
Console.WriteLine("Client Name\tCPU%\tMemory(MB)\tDisk(MB)\tLast Updated");
Console.WriteLine("-------------------------------------------------------------");
lock (clientStatus)
{
foreach (var client in clientStatus)
{
var info = client.Value;
TimeSpan sinceUpdate = DateTime.Now - info.LastUpdated;
string status = sinceUpdate.TotalSeconds > 30 ? "OFFLINE" : "ONLINE";
Console.WriteLine($"{info.ClientName}\t{info.CpuUsage:F1}%\t{info.MemoryUsageMB:F0}\t\t{info.DiskSpaceMB}\t\t{status}");
}
}
}
public void Stop()
{
displayTimer.Dispose();
server.Stop();
}
static void Main(string[] args)
{
var monitor = new MonitorServer();
try
{
monitor.Start();
}
finally
{
monitor.Stop();
}
}
}
Client Agent
using AaTurpin.NamedPipes;
using RunLog;
using System;
using System.Diagnostics;
using System.IO;
using System.Management;
using System.Text.Json;
using System.Threading;
class MonitorClient
{
private NamedPipeClient client;
private string clientName;
private Timer updateTimer;
private readonly string serverName;
// Class matching the server's SystemInfo
public class SystemInfo
{
public string ClientName { get; set; }
public double CpuUsage { get; set; }
public double MemoryUsageMB { get; set; }
public long DiskSpaceMB { get; set; }
public DateTime LastUpdated { get; set; }
}
public MonitorClient(string clientName, string serverName = ".")
{
this.clientName = clientName;
this.serverName = serverName;
// Setup logging
var logsDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
Directory.CreateDirectory(logsDir);
var logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File(Path.Combine(logsDir, "monitor-client-.log"),
rollingInterval: RollingInterval.Day)
.CreateLogger();
Log.Logger = logger;
// Create client
client = new NamedPipeClient(
pipeName: "MonitorPipe",
serverName: serverName,
reconnectDelay: 2000,
maxRetries: 10);
}
public void Start()
{
if (client.Connect(autoReconnect: true))
{
Console.WriteLine($"Connected to monitor server on {serverName}");
// Send updates every 5 seconds
updateTimer = new Timer(SendUpdate, null, 0, 5000);
Console.WriteLine("Monitoring agent started. Press Enter to quit.");
Console.ReadLine();
}
else
{
Console.WriteLine($"Failed to connect to monitor server on {serverName}");
}
}
private void SendUpdate(object state)
{
if (!client.IsConnected)
{
Console.WriteLine("Not connected to server. Waiting for reconnection...");
return;
}
try
{
var systemInfo = new SystemInfo
{
ClientName = clientName,
CpuUsage = GetCpuUsage(),
MemoryUsageMB = GetMemoryUsage(),
DiskSpaceMB = GetDiskSpace()
};
string json = JsonSerializer.Serialize(systemInfo);
string response = client.SendCommand(json);
if (response != "OK")
{
Console.WriteLine($"Server error: {response}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error sending update: {ex.Message}");
}
}
private double GetCpuUsage()
{
// This is a simplified example - in a real app, you'd use PerformanceCounter
// or other methods to get accurate CPU usage
try
{
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
cpuCounter.NextValue(); // First call always returns 0
Thread.Sleep(500);
return cpuCounter.NextValue();
}
catch
{
// Fallback to random value for demo purposes
return new Random().Next(1, 100);
}
}
private double GetMemoryUsage()
{
try
{
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem"))
{
foreach (var obj in searcher.Get())
{
var totalPhysicalMemory = Convert.ToDouble(obj["TotalVisibleMemorySize"]);
var freePhysicalMemory = Convert.ToDouble(obj["FreePhysicalMemory"]);
return (totalPhysicalMemory - freePhysicalMemory) / 1024; // Convert from KB to MB
}
}
}
catch
{
// Fallback
}
// Fallback to less accurate method
return GC.GetTotalMemory(false) / (1024 * 1024);
}
private long GetDiskSpace()
{
try
{
DriveInfo drive = new DriveInfo(Path.GetPathRoot(Environment.SystemDirectory));
return drive.AvailableFreeSpace / (1024 * 1024); // Convert to MB
}
catch
{
return 10000; // Fallback value
}
}
public void Stop()
{
updateTimer?.Dispose();
client.Disconnect();
}
static void Main(string[] args)
{
string computerName = Environment.MachineName;
string serverName = "."; // Use "." for local machine
if (args.Length > 0)
{
serverName = args[0];
}
var agent = new MonitorClient(computerName, serverName);
try
{
agent.Start();
}
finally
{
agent.Stop();
}
}
}
API Reference
NamedPipeServer
// Constructor
public NamedPipeServer(string pipeName, CommandHandler commandHandler)
// Methods
public void Start()
public void Stop()
public void Dispose()
// Static Methods
public static void SetLogger(Logger logger)
NamedPipeClient
// Constructor
public NamedPipeClient(
string pipeName,
string serverName = ".",
ResponseHandler responseHandler = null,
int connectionTimeout = 5000,
int reconnectDelay = 1000,
int maxRetries = 5)
// Properties
public bool IsConnected { get; }
// Methods
public bool Connect(bool autoReconnect = false)
public void Disconnect()
public string SendCommand(string command)
public void Dispose()
// Static Methods
public static void SetLogger(Logger logger)
Compatibility
- .NET Framework 4.7.2 or higher
- .NET Core 3.1 or higher
- .NET 5.0 or higher
License
MIT License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET Framework | net472 is compatible. net48 was computed. net481 was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
.NETFramework 4.7.2
- RunLog (>= 3.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|
Initial Release.