How to: Use Anonymous Pipes to Communicate Between Local Processes

Anonymous pipes offer less functionality than named pipes, but also require less overhead. You can use anonymous pipes to make interprocess communication on a local computer easier. You cannot use anonymous pipes for communication over a network.

Example

The following example demonstrates a way to send a string from a parent process to a child process using anonymous pipes. This example creates an AnonymousPipeServerStream object in a parent process with a PipeDirection value of Out. The parent process then creates a child process by using a client handle to create an AnonymousPipeClientStream object. The child process has a PipeDirection value of In.

The parent process then sends a user-supplied string to the child process. The string is displayed to the console in the child process.

The following example shows the server process.

Imports System
Imports System.IO
Imports System.IO.Pipes
Imports System.Diagnostics

Class PipeServer
    Shared Sub Main()
        Dim pipeClient As New Process()

        pipeClient.StartInfo.FileName = "pipeClient.exe" 

        Using pipeServer As New AnonymousPipeServerStream(PipeDirection.Out, _
            HandleInheritability.Inheritable)

            ' Show that anonymous pipes do not support Message mode. 
            Try
                Console.WriteLine("[SERVER] Setting ReadMode to ""Message"".")
                pipeServer.ReadMode = PipeTransmissionMode.Message
            Catch e As NotSupportedException
                Console.WriteLine("[SERVER] Exception:\n    {0}", e.Message)
            End Try

            Console.WriteLine("[SERVER] Current TransmissionMode: {0}.", _
                pipeServer.TransmissionMode)

            ' Pass the client process a handle to the server.
            pipeClient.StartInfo.Arguments = pipeServer.GetClientHandleAsString()
            pipeClient.StartInfo.UseShellExecute = false
            pipeClient.Start()

            pipeServer.DisposeLocalCopyOfClientHandle()

            Try 
                ' Read user input and send that to the client process. 
                Using sw As New StreamWriter(pipeServer)
                    sw.AutoFlush = true
                    ' Send a 'sync message' and wait for client to receive it.
                    sw.WriteLine("SYNC")
                    pipeServer.WaitForPipeDrain()
                    ' Send the console input to the client process.
                    Console.Write("[SERVER] Enter text: ")
                    sw.WriteLine(Console.ReadLine())
                End Using 
            Catch e As IOException
                ' Catch the IOException that is raised if the pipe is broken 
                ' or disconnected.
                Console.WriteLine("[SERVER] Error: {0}", e.Message)
            End Try 
        End Using

        pipeClient.WaitForExit()
        pipeClient.Close()
        Console.WriteLine("[SERVER] Client quit. Server terminating.")
    End Sub 
End Class
using System;
using System.IO;
using System.IO.Pipes;
using System.Diagnostics;

class PipeServer
{
    static void Main()
    {
        Process pipeClient = new Process();

        pipeClient.StartInfo.FileName = "pipeClient.exe";

        using (AnonymousPipeServerStream pipeServer =
            new AnonymousPipeServerStream(PipeDirection.Out,
            HandleInheritability.Inheritable))
        {
            // Show that anonymous pipes do not support Message mode. 
            try
            {
                Console.WriteLine("[SERVER] Setting ReadMode to \"Message\".");
                pipeServer.ReadMode = PipeTransmissionMode.Message;
            }
            catch (NotSupportedException e)
            {
                Console.WriteLine("[SERVER] Exception:\n    {0}", e.Message);
            }

            Console.WriteLine("[SERVER] Current TransmissionMode: {0}.",
                pipeServer.TransmissionMode);

            // Pass the client process a handle to the server.
            pipeClient.StartInfo.Arguments =
                pipeServer.GetClientHandleAsString();
            pipeClient.StartInfo.UseShellExecute = false;
            pipeClient.Start();

            pipeServer.DisposeLocalCopyOfClientHandle();

            try
            {
                // Read user input and send that to the client process. 
                using (StreamWriter sw = new StreamWriter(pipeServer))
                {
                    sw.AutoFlush = true;
                    // Send a 'sync message' and wait for client to receive it.
                    sw.WriteLine("SYNC");
                    pipeServer.WaitForPipeDrain();
                    // Send the console input to the client process.
                    Console.Write("[SERVER] Enter text: ");
                    sw.WriteLine(Console.ReadLine());
                }
            }
            // Catch the IOException that is raised if the pipe is broken 
            // or disconnected. 
            catch (IOException e)
            {
                Console.WriteLine("[SERVER] Error: {0}", e.Message);
            }
        }

        pipeClient.WaitForExit();
        pipeClient.Close();
        Console.WriteLine("[SERVER] Client quit. Server terminating.");
    }
}

The following example shows the client process. The server process starts the client process and gives that process a client handle. The resulting executable from the client code should be named pipeClient.exe and be copied to the same directory as the server executable before running the server process.

Imports System
Imports System.IO
Imports System.IO.Pipes

Class PipeClient
    Shared Sub Main(args() as String)
        If args.Length > 0 Then 
            Using pipeClient As New AnonymousPipeClientStream(PipeDirection.In, args(0))
                ' Show that anonymous Pipes do not support Message mode. 
                Try
                    Console.WriteLine("[CLIENT] Setting ReadMode to ""Message"".")
                    pipeClient.ReadMode = PipeTransmissionMode.Message
                Catch e As NotSupportedException
                    Console.WriteLine("[CLIENT] Execption:" + vbNewLine + "    {0}", e.Message)
                End Try

                Console.WriteLine("[CLIENT] Current TransmissionMode: {0}.", _
                   pipeClient.TransmissionMode)

                Using sr As New StreamReader(pipeClient)
                    ' Display the read text to the console 
                    Dim temp As String 

                    ' Wait for 'sync message' from the server. 
                    Do
                        Console.WriteLine("[CLIENT] Wait for sync...")
                        temp = sr.ReadLine()
                    Loop While temp.StartsWith("SYNC") = False 

                    ' Read the server data and echo to the console.
                    temp = sr.ReadLine()
                    While Not temp = Nothing
                        Console.WriteLine("[CLIENT] Echo: " + temp)
                        temp = sr.ReadLine()
                    End While 
                End Using 
            End Using 
        End If
        Console.Write("[CLIENT] Press Enter to continue...")
        Console.ReadLine()
    End Sub 
End Class
using System;
using System.IO;
using System.IO.Pipes;

class PipeClient
{
    static void Main(string[] args)
    {
        if (args.Length > 0)
        {
            using (PipeStream pipeClient =
                new AnonymousPipeClientStream(PipeDirection.In, args[0]))
            {
                // Show that anonymous Pipes do not support Message mode. 
                try
                {
                    Console.WriteLine("[CLIENT] Setting ReadMode to \"Message\".");
                    pipeClient.ReadMode = PipeTransmissionMode.Message;
                }
                catch (NotSupportedException e)
                {
                    Console.WriteLine("[CLIENT] Execption:\n    {0}", e.Message);
                }

                Console.WriteLine("[CLIENT] Current TransmissionMode: {0}.",
                   pipeClient.TransmissionMode);

                using (StreamReader sr = new StreamReader(pipeClient))
                {
                    // Display the read text to the console 
                    string temp;

                    // Wait for 'sync message' from the server. 
                    do
                    {
                        Console.WriteLine("[CLIENT] Wait for sync...");
                        temp = sr.ReadLine();
                    }
                    while (!temp.StartsWith("SYNC"));

                    // Read the server data and echo to the console. 
                    while ((temp = sr.ReadLine()) != null)
                    {
                        Console.WriteLine("[CLIENT] Echo: " + temp);
                    }
                }
            }
        }
        Console.Write("[CLIENT] Press Enter to continue...");
        Console.ReadLine();
    }
}

See Also

Tasks

How to: Use Named Pipes to Communicate Between Processes over a Network

Concepts

Pipes