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" />
                    
Directory.Packages.props
<PackageReference Include="AaTurpin.NamedPipes" />
                    
Project file
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
                    
#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
                    
Install as a Cake Addin
#tool nuget:?package=AaTurpin.NamedPipes&version=1.0.0
                    
Install as a Cake Tool

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 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

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.