Gewusst wie: Verwenden von anonymen Pipes zur Kommunikation zwischen lokalen Prozessen
Anonyme Pipes bieten zwar weniger Funktionen als benannte Pipes, erfordern aber auch weniger Mehraufwand. Sie können anonyme Pipes verwenden, um die prozessübergreifende Kommunikation auf einem lokalen Computer zu vereinfachen. Anonyme Pipes können nicht zur Kommunikation über ein Netzwerk verwendet werden.
Beispiel
Das folgende Beispiel zeigt, wie eine Zeichenfolge mithilfe von anonymen Pipes von einem übergeordneten Prozess an einen untergeordneten Prozess gesendet werden kann. In diesem Beispiel wird ein AnonymousPipeServerStream-Objekt in einem übergeordneten Prozess mit dem PipeDirection-Wert Out erstellt. Anschließend wird vom übergeordneten Prozess ein untergeordneter Prozess erstellt, indem ein Clienthandle zur Erstellung eines AnonymousPipeClientStream-Objekts verwendet wird. Der untergeordnete Prozess hat den PipeDirection-Wert In.
Der übergeordnete Prozess sendet daraufhin eine vom Benutzer bereitgestellte Zeichenfolge an den untergeordneten Prozess. Die Zeichenfolge wird im untergeordneten Prozess auf der Konsole angezeigt.
Das folgende Codebeispiel zeigt den Serverprozess:
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.");
}
}
#using <System.dll>
#using <System.Core.dll>
using namespace System;
using namespace System::IO;
using namespace System::IO::Pipes;
using namespace System::Diagnostics;
ref class PipeServer
{
public:
static void Main()
{
Process^ pipeClient = gcnew Process();
pipeClient->StartInfo->FileName = "pipeClient.exe";
AnonymousPipeServerStream^ pipeServer =
gcnew 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.
StreamWriter^ sw = gcnew 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());
sw->Close();
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException^ e)
{
Console::WriteLine("[SERVER] Error: {0}", e->Message);
}
pipeServer->Close();
pipeClient->WaitForExit();
pipeClient->Close();
Console::WriteLine("[SERVER] Client quit. Server terminating.");
}
};
int main()
{
PipeServer::Main();
}
Das folgende Codebeispiel zeigt den Clientprozess: Der Serverprozess startet den Clientprozess und übergibt ein Clienthandle an diesen Prozess. Die resultierende ausführbare Datei aus dem Clientcode sollte pipeClient.exe genannt und in dasselbe Verzeichnis kopiert werden wie die ausführbare Datei des Servers, bevor der Serverprozess ausgeführt wird.
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();
}
}
#using <System.Core.dll>
using namespace System;
using namespace System::IO;
using namespace System::IO::Pipes;
ref class PipeClient
{
public:
static void Main(array<String^>^ args)
{
if (args->Length > 1)
{
PipeStream^ pipeClient = gcnew AnonymousPipeClientStream(PipeDirection::In, args[1]);
// 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);
StreamReader^ sr = gcnew 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()) != nullptr)
{
Console::WriteLine("[CLIENT] Echo: " + temp);
}
sr->Close();
pipeClient->Close();
}
Console::Write("[CLIENT] Press Enter to continue...");
Console::ReadLine();
}
};
int main()
{
array<String^>^ args = Environment::GetCommandLineArgs();
PipeClient::Main(args);
}
Siehe auch
Aufgaben
Gewusst wie: Verwenden von benannten Pipes zur Kommunikation zwischen Prozessen über ein Netzwerk