Giter Site home page Giter Site logo

named-pipe-wrapper's Introduction

Named Pipe Wrapper for .NET 4.0

A simple, easy to use, strongly-typed wrapper around .NET named pipes.

NuGet Package

Available as a NuGet package.

Features

  • Create named pipe servers that can handle multiple client connections simultaneously.
  • Send strongly-typed messages between clients and servers: any serializable .NET object can be sent over a pipe and will be automatically serialized/deserialized, including cyclical references and complex object graphs.
  • Messages are sent and received asynchronously on a separate background thread and marshalled back to the calling thread (typically the UI).
  • Supports large messages - up to 300 MiB.

Requirements

Requires .NET 4.0 full.

Usage

Message:

(Class must have a [Serializable] attribute)

[Serializable]
class SomeClass
{
    public int Id;
    public string Text;
}

Server:

var server = new NamedPipeServer<SomeClass>("MyServerPipe");

server.ClientConnected += delegate(NamedPipeConnection<SomeClass> conn)
    {
        Console.WriteLine("Client {0} is now connected!", conn.Id);
        conn.PushMessage(new SomeClass { Text: "Welcome!" });
    };

server.ClientMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message)
    {
        Console.WriteLine("Client {0} says: {1}", conn.Id, message.Text);
    };

// Start up the server asynchronously and begin listening for connections.
// This method will return immediately while the server runs in a separate background thread.
server.Start();

// ...

Client:

var client = new NamedPipeClient<SomeClass>("MyServerPipe");

client.ServerMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message)
    {
        Console.WriteLine("Server says: {0}", message.Text);
    };

// Start up the client asynchronously and connect to the specified server pipe.
// This method will return immediately while the client runs in a separate background thread.
client.Start();

// ...

MIT License

Named Pipe Wrapper for .NET is licensed under the MIT license.

named-pipe-wrapper's People

Contributors

acdvorak avatar marinkobabic avatar siyo-wang avatar sporty81 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

named-pipe-wrapper's Issues

System.UnauthorizedAccessException: Access to the path is denied.

Hello,

I'm using version 1.5.0 downloaded from NuGet's repositories and when trying the code you have in the README.md I got this exception:

System.UnauthorizedAccessException: Access to the path is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Pipes.NamedPipeClientStream.Connect(Int32 timeout)
   at NamedPipeWrapper.NamedPipeClient`2.ListenSync()
   at NamedPipeWrapper.Threading.Worker.DoWorkImpl(Object oAction)

I see you added some configuration for security after 1.5.0 but while you release the final version of 1.5.3, is there a sample of code that works with 1.5.0?

The sample project you have in the repo is using version 1.4.0's DLL instead, but the code of the NamedPipeWrapper project seems to be for 1.5.3-Beta.

In case it's important, my use case is: I create the server pipe in a Windows' service and the client in a GUI app.

Also, where can I find the exact source code that you released in NuGet as 1.5.0 ? I didn't find version tags in this repo.

Thanks.

Occasionally getting Error: Object Graph cannot be null

Seeing this error occasionally. Any fix can be applied?

Object Graph cannot be null.
Parameter name: graph
mscorlib
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
at NamedPipeWrapper.IO.PipeStreamWriter1.Serialize(T obj) in C:\BitBucket\named-pipe-wrapper\NamedPipeWrapper\IO\PipeStreamWriter.cs:line 42 at NamedPipeWrapper.NamedPipeConnection2.WritePipe() in C:\BitBucket\named-pipe-wrapper\NamedPipeWrapper\NamedPipeConnection.cs:line 167
at NamedPipeWrapper.Threading.Worker.DoWorkImpl(Object oAction) in C:\BitBucket\named-pipe-wrapper\NamedPipeWrapper\Threading\Worker.cs:line 46

From NamedPipeClient how can I tell if I am connected?

When connecting from the client, there seems to be no way to tell if there server is actually running and the connection is up. In the following code:

			_pipe = new NamedPipeClient<OA_Message>(PipeName);
			_pipe.ServerMessage += _pipe_ServerMessage;
			_pipe.Error += (ex) => _error = ex.ToString();
			_pipe.Disconnected += _pipe_Disconnected;
			_pipe.Start();
			_pipe.WaitForConnection(300);

Everything goes fine as if it worked, except that the server is not running the the pipe is not connected. Within the NamedPipeClient there is a protected member _connection that is NULL in this case, but I can't check it because it is private. It seems like there should be some kind of IsConnected property, or that the Error callback should be called if there isn't a server to connect with...

Am I missing something?

Is it Thread Safe?

Hi,

Am getting this message every time multiple threads try to write to a single pipe. Is it thread safe? I locked on a client to push messages one at a time, but still getting this error. Once you see it the whole connection is dead.

Any suggestions?

Thanks!

Object Graph cannot be null.\r\nParameter name: graph

at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
at NamedPipeWrapper.IO.PipeStreamWriter1.Serialize(T obj) in C:\Projects\NamedPipeWrapper\NamedPipeWrapper\IO\PipeStreamWriter.cs:line 42 at NamedPipeWrapper.IO.PipeStreamWriter1.WriteObject(T obj) in C:\Projects\NamedPipeWrapper\NamedPipeWrapper\IO\PipeStreamWriter.cs:line 72
at NamedPipeWrapper.IO.PipeStreamWrapper2.WriteObject(TWrite obj) in C:\Projects\NamedPipeWrapper\NamedPipeWrapper\IO\PipeStreamWrapper.cs:line 106 at NamedPipeWrapper.NamedPipeConnection2.WritePipe() in C:\Projects\NamedPipeWrapper\NamedPipeWrapper\NamedPipeConnection.cs:line 167
at NamedPipeWrapper.Threading.Worker.DoWorkImpl(Object oAction) in C:\Projects\NamedPipeWrapper\NamedPipeWrapper\Threading\Worker.cs:line 46

Frequent create NamedPipeClient instance to Connect Server can cause memory leak

Frequent create NamedPipeClient instance to Connect Server can cause memory leak
Task.Factory.StartNew(() => { while (true) { i++; NamedPipeClient<string> _client2 = new NamedPipeClient<string>(Constants.PIPE_NAME); _client2.ServerMessage += OnServerMessage; _client2.Disconnected += OnDisconnected; _client2.Start(); _client2.PushMessage("this is the " + i + "client"); _client2.Stop(); _client2.ServerMessage -= OnServerMessage; _client2.Disconnected -= OnDisconnected; Thread.Sleep(200); } });

.NET 6 support?

Dear devs,

thanks for this amazing packet, is there a .NET 6 support planed for the future?

Thank you! :)

Really bad error handling

Please change this part of your implementation:

        /// <summary>
        ///     Invoked on the background thread.
        /// </summary>
        /// <exception cref="SerializationException">An object in the graph of type parameter <typeparamref name="TWrite"/> is not marked as serializable.</exception>
        private void WritePipe()
        {

            while (IsConnected && _streamWrapper.CanWrite)
            {
                try
                {
                    //using blockcollection, we needn't use singal to wait for result.
                    //_writeSignal.WaitOne();
                    //while (_writeQueue.Count > 0)
                    {
                        _streamWrapper.WriteObject(_writeQueue.Take());
                        _streamWrapper.WaitForPipeDrain();
                    }
                }
                catch
                {
                    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    //we must igonre exception, otherwise, the namepipe wrapper will stop work.
                    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                }
            }

        }

If WriteObject fails, it's really impossible to understand why the message was not sent.

For example using a non serializable static variable in a private method of the class used as pipe message.

Thank you,
Filippo.

0x64 to 0x86 serialisation issue

Hi
I'm building a solution with two projects - the Client is a 8x64 project and the Server is 0x86
When i send a message across to the server there is a serialisation problem

The thread 0x210c has exited with code 0 (0x0).
The thread 0x2134 has exited with code 0 (0x0).
'MyCaller.vshost.exe' (CLR v4.0.30319: MyCaller.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Accessibility\v4.0_4.0.0.0__b03f5f7f11d50a3a\Accessibility.dll'. Symbols loaded.
'MyCaller.vshost.exe' (CLR v4.0.30319: MyCaller.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationProvider\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationProvider.dll'. Symbols loaded.
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll
Exception thrown: 'System.Runtime.Serialization.SerializationException' in mscorlib.dll

when i build both systems in 0x86 everything works just fine and messages go back and forth as expected.

For background information -I am using named pipes betwen 0x64 and 0x86 to control a 0x86 COM object that cannot be rewritten in to 0x64

What modifications do i need to make to make this serialisation issue work?

Buzz

is it possible to run in unity?

I have tried to import this dll to my unity, and can compile it successfully,
but it seems to not work.
I setup a pipe server in my unity, but no client can connect to it.
I set my unity run-time environment to match Net 4.0+, but it seems to not work.
Is it possible to run in unity?
Thanks advance if you have time to check this issue.

JSON Serialization

Not sure if this still has support but I had high hopes until I discovered it uses XML serialization to instantiate types. I need to use between 2 projects that do not share the same type reference.

PushMessage in the client doesn't seem to work

I cannot get the PushMessage() function in the client to send anything to the server.
Client is doing something like this:

                    var pipeClient = new NamedPipeClient<IpcInfo>(pipeName);
                    pipeClient.Start();
                    pipeClient.WaitForConnection();
                    var message = new IpcInfo();
                    pipeClient.PushMessage(message);
                    pipeClient.WaitForDisconnection();
                    pipeClient.Stop();

Server like this:

                    var pipeServer = new NamedPipeServer<IpcInfo>(pipeName);
                    pipeServer.ClientConnected += delegate (NamedPipeConnection<IpcInfo, IpcInfo> conn)
                    {
                    };

                    pipeServer.ClientMessage += delegate (NamedPipeConnection<IpcInfo, IpcInfo> conn, IpcInfo message)
                    {
                        conn.Close();
                    };
                    var application = new App();
                    application.InitializeComponent();
                    pipeServer.Start();
                    application.Run();
                    pipeServer.Stop();

I get a callback for ClientConnected, but not in ClientMessage. Client is waiting for disconnect.

Connect over network, through IP.

To connect between client and server, works perfect if it is on the same machine.
server = new NamedPipeServer("named_pipe_test_server");
client = new NamedPipeClient("named_pipe_test_server");

How is the syntax for connecting over network, through IP?
like "//192.168.100.1//namedPipeTestServer" or ??

How to initialize client and server if both exes are located in a network share but are running in the same PC

I have two apps that are using named-pipe-weapper, bot apps, client and server are executed from a network share but are running in the same PC.

When I run both apps from local harddrive it works fine, but running from the network share is not working.

Any idea how to initalize client and server?

EDIT: I'm using the name of the machine as connection name instead ".". It works on some machines (3 Windows 10) but it fails in a Windows 7 and in a Windows Server machine.

console example does not work ... below fix I found

MyServer.cs:

    private bool KeepRunning
    {
        get
        {
            msg = Console.ReadLine();
            //Console.ReadKey();
            //if (key.Key == ConsoleKey.Q)
            if (string.Equals(msg, "q", StringComparison.OrdinalIgnoreCase))
                return false;
            return true;
        }
    }

    public MyServer(string pipeName)
    {
        var server = new NamedPipeServer<MyMessage>(pipeName);
        server.ClientConnected += OnClientConnected;
        server.ClientDisconnected += OnClientDisconnected;
        server.ClientMessage += OnClientMessage;
        server.Error += OnError;
        server.Start();
        while (KeepRunning)
        {
            // Do nothing - wait for user to press 'q' key
            server.PushMessage(new MyMessage
            {
                Id = new Random().Next(),
                Text = msg
            });
        }
        server.Stop();
    }

MyClient.cs:

    private bool KeepRunning
    {
        get
        {
            msg = Console.ReadLine();
            //var key = Console.ReadKey();
            //if (key.Key == ConsoleKey.Q)
            if (string.Equals(msg, "q", StringComparison.OrdinalIgnoreCase))
                return false;
            return true;
        }
    }

    public MyClient(string pipeName)
    {
        var client = new NamedPipeClient<MyMessage>(pipeName);
        client.ServerMessage += OnServerMessage;
        client.Error += OnError;
        client.Start();
        while (KeepRunning)
        {
            // Do nothing - wait for user to press 'q' key
            client.PushMessage(new MyMessage
            {
                Id = new Random().Next(),
                Text = msg
            });
        }
        client.Stop();
    }

High CPU Usage

Hi,

I have a client in a WindowsService which does the following:

var client = new NamedPipeClient<string>("my-pipe");
client.Start();

The UI application acts as the server:

var server = new NamedPipeServer<string>("my-pipe");
server.ClientMessage += OnClientMessage;
server.Start();

Problem:
If my UI application is closed the CPU Usage goes up to 100% on one core.
I guess this is due a missing sleep where the client tries to connect to the server.

Greetings thaxy

Edit:
This Issue was fixed with this reliablehosting@f7267a4 commit in this pull request #3 I hope that acdvorak will update this with his own code. His syntax and knowledge is awesome.

NamedPipeServer with different types for Read and Write (as NamedPipeClient)

NamedPipeServer only supports specify a TReadWrite but sometimes is interesting use a different type for readings and other for writings.

Please, create a new NamedPipeServer class accepting two generic arguments as NamedPipeClient does.

I've implemented my own class:

public class NamedPipeServer<TRead, TWrite> : NamedPipeWrapper.Server<TRead, TWrite> where TRead : class where TWrite : class
{
	public NamedPipeServer(string pipeName)
		: base(pipeName, null) { }

	public NamedPipeServer(string pipeName, PipeSecurity pipeSecurity)
		: base(pipeName, pipeSecurity) { }
}

But it would be better if you do it in your library

Thank you.

Does it work with all servers?

I want to connect to a third party application that runs it's own pipe server (probably using NamedPipeServerStream). Should the NamedPipeClient work with any implementation or just the NamedPipeServer?

I'm asking because I can't get it to connect, it hangs on handshake.ReadObject() in ListenSync. Thanks!

Server stops receiving client messages after an exception occurs

Hello,

I am using this code to receive messages from pipe clients:

      _pipeServer = new NamedPipeServer<CommandServer.Ipc.Message>(CommandServer.Command.PipeServerName);
      _pipeServer.ClientConnected += delegate (NamedPipeConnection<CommandServer.Ipc.Message, CommandServer.Ipc.Message> connection)
      {
          ////
      };
      _pipeServer.ClientDisconnected += delegate (NamedPipeConnection<CommandServer.Ipc.Message, CommandServer.Ipc.Message> connection)
      {
          ////
      };
      _pipeServer.Error += delegate (Exception exception)
      {
          ////
      };
      _pipeServer.ClientMessage += delegate (NamedPipeConnection<CommandServer.Ipc.Message, CommandServer.Ipc.Message> connection, CommandServer.Ipc.Message message)
      {
         ////
      };

Almost all works perfectly. _pipeServer.ClientMessage continues receiving messages from clients, however, when inside ClientMessage an exception occurs and the _pipeServer.Error event is called, server stops receiving client messages.

I tried calling _pipeServer.Start(); again in the Error event, but it did not work.

If I close the server application and start it again, it starts receiving client messages again.

Any help, please?

Thanks
Jaime

how to use named pipe client in asp application

Hi,

I had extracted the namedpipe wrapper from the github and used in the c# .net core wpf application.

The wpf application is working fine and no issues

And i had created an asp application, set the console app as a server and the asp application as a client.

When i ran the code i got this exception

image

When i searched about the code i understood that because some of the code in here is obsolete and asp wont support these code. These feature removed from asp application

image

so when i searched about this error , found some suggestions to use the jsonserialiser instead of binaryformatter

but when i execute this execption is occurring

image

Broken error handling

If I start a server instance

var server = new NamedPipeServer<TestClass>("MyServerPipe");
server.Start();

the failure of pipe creation is not detectable. There can be an error (for example the pipe is busy), which is simply written to console output, but no events are thrown (Error). This code causes the problem:

while (this._shouldKeepRunning)
    this.WaitForConnection(this._pipeName);

in this.WaitForConnections this can fail:

pipe1 = PipeServerFactory.CreateAndConnectPipe(pipeName) 

and then the error is handled in try catch, but while cycle keeps running and tries again and no error event is thrown.

So how to detect if server.Start was unsuccessful?

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.