Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ExampleCLI/ExampleCLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<OutputPath>..\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
Expand Down
2 changes: 1 addition & 1 deletion ExampleGUI/ExampleGUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<OutputPath>..\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
Expand Down
12 changes: 10 additions & 2 deletions ExampleGUI/FormServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,16 @@ private void buttonSend_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(textBoxMessage.Text))
return;

_server.PushMessage(textBoxMessage.Text);
if (listBoxClients.SelectedItem == null)
{
_server.PushMessage(textBoxMessage.Text);
}
else
{
var clientName = listBoxClients.SelectedItem.ToString();
_server.PushMessage(textBoxMessage.Text, clientName);
}

textBoxMessage.Text = "";
}
}
Expand Down
51 changes: 48 additions & 3 deletions NamedPipeWrapper/NamedPipeClient.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using NamedPipeWrapper.IO;
Expand Down Expand Up @@ -40,6 +42,14 @@ public class NamedPipeClient<TRead, TWrite>
/// </summary>
public bool AutoReconnect { get; set; }

/// <summary>
/// Gets or sets how long the client waits between a reconnection attempt.
/// Default value is <c>0</c>.
/// </summary>
public int AutoReconnectDelay { get; set; }



/// <summary>
/// Invoked whenever a message is received from the server.
/// </summary>
Expand Down Expand Up @@ -77,7 +87,7 @@ public NamedPipeClient(string pipeName)
/// Connects to the named pipe server asynchronously.
/// This method returns immediately, possibly before the connection has been established.
/// </summary>
public void Start()
public void Start(bool waitForconnection = false)
{
_closedExplicitly = false;
var worker = new Worker();
Expand Down Expand Up @@ -141,6 +151,8 @@ public void WaitForDisconnection(TimeSpan timeout)

#region Private methods



private void ListenSync()
{
// Get the name of the data pipe that should be used from now on by this NamedPipeClient
Expand Down Expand Up @@ -170,7 +182,10 @@ private void OnDisconnected(NamedPipeConnection<TRead, TWrite> connection)

// Reconnect
if (AutoReconnect && !_closedExplicitly)
{
Thread.Sleep(AutoReconnectDelay);
Start();
}
}

private void OnReceiveMessage(NamedPipeConnection<TRead, TWrite> connection, TRead message)
Expand Down Expand Up @@ -202,17 +217,47 @@ private void OnError(Exception exception)

static class PipeClientFactory
{
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool WaitNamedPipe(string name, int timeout);

public static bool NamedPipeExists(string pipeName)
{
try
{
bool exists = WaitNamedPipe(pipeName, -1);
if (!exists)
{
int error = Marshal.GetLastWin32Error();
if (error == 0 || error == 2)
{
return false;
}
}
return true;
}
catch (Exception ex)
{
return false;
}
}

public static PipeStreamWrapper<TRead, TWrite> Connect<TRead, TWrite>(string pipeName)
where TRead : class
where TWrite : class
{
return new PipeStreamWrapper<TRead, TWrite>(CreateAndConnectPipe(pipeName));
}

public static NamedPipeClientStream CreateAndConnectPipe(string pipeName)
public static NamedPipeClientStream CreateAndConnectPipe(string pipeName, int timeout = 10)
{
string normalizedPath = Path.GetFullPath(string.Format(@"\\.\pipe\{0}", pipeName));
while (!NamedPipeExists(normalizedPath))
{
Thread.Sleep(timeout);
}
var pipe = CreatePipe(pipeName);
pipe.Connect();
pipe.Connect(1000);
return pipe;
}

Expand Down
7 changes: 7 additions & 0 deletions NamedPipeWrapper/NamedPipeConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO.Pipes;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -29,6 +30,11 @@ public class NamedPipeConnection<TRead, TWrite>
/// </summary>
public readonly string Name;

/// <summary>
/// Gets the connection's handle.
/// </summary>
public readonly SafeHandle Handle;

/// <summary>
/// Gets a value indicating whether the pipe is connected or not.
/// </summary>
Expand Down Expand Up @@ -60,6 +66,7 @@ internal NamedPipeConnection(int id, string name, PipeStream serverStream)
{
Id = id;
Name = name;
Handle = serverStream.SafePipeHandle;
_streamWrapper = new PipeStreamWrapper<TRead, TWrite>(serverStream);
}

Expand Down
Loading