diff --git a/.vs/NamedPipeWrapper/DesignTimeBuild/.dtbcache.v2 b/.vs/NamedPipeWrapper/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000..ade4d80 Binary files /dev/null and b/.vs/NamedPipeWrapper/DesignTimeBuild/.dtbcache.v2 differ diff --git a/NamedPipeWrapper/IO/PipeStreamReader.cs b/NamedPipeWrapper/IO/PipeStreamReader.cs index 187609f..4836cdd 100644 --- a/NamedPipeWrapper/IO/PipeStreamReader.cs +++ b/NamedPipeWrapper/IO/PipeStreamReader.cs @@ -1,4 +1,5 @@ -using System; +using ProtoBuf; +using System; using System.Collections.Generic; using System.IO; using System.IO.Pipes; @@ -68,7 +69,8 @@ private T ReadObject(int len) BaseStream.Read(data, 0, len); using (var memoryStream = new MemoryStream(data)) { - return (T) _binaryFormatter.Deserialize(memoryStream); + return Serializer.Deserialize(memoryStream); + //return (T) _binaryFormatter.Deserialize(memoryStream); } } diff --git a/NamedPipeWrapper/IO/PipeStreamWriter.cs b/NamedPipeWrapper/IO/PipeStreamWriter.cs index 9ebeb3f..09e3e5d 100644 --- a/NamedPipeWrapper/IO/PipeStreamWriter.cs +++ b/NamedPipeWrapper/IO/PipeStreamWriter.cs @@ -1,3 +1,4 @@ +using ProtoBuf; using System; using System.Collections.Generic; using System.IO; @@ -41,11 +42,12 @@ private byte[] Serialize(T obj) { using (var memoryStream = new MemoryStream()) { - _binaryFormatter.Serialize(memoryStream, obj); + Serializer.Serialize(memoryStream, obj); + //_binaryFormatter.Serialize(memoryStream, obj); return memoryStream.ToArray(); } } - catch + catch (Exception ex) { //if any exception in the serialize, it will stop named pipe wrapper, so there will ignore any exception. return null; diff --git a/NamedPipeWrapper/NamedPipeClient.cs b/NamedPipeWrapper/NamedPipeClient.cs index a1132c5..d15ceeb 100644 --- a/NamedPipeWrapper/NamedPipeClient.cs +++ b/NamedPipeWrapper/NamedPipeClient.cs @@ -80,6 +80,8 @@ public NamedPipeClient(string pipeName,string serverName) AutoReconnect = true; } + + /// /// Connects to the named pipe server asynchronously. /// This method returns immediately, possibly before the connection has been established. @@ -89,9 +91,10 @@ public void Start() _closedExplicitly = false; var worker = new Worker(); worker.Error += OnError; - worker.DoWork(ListenSync); + worker.DoWork(ListenSync, CancellationToken.None); } + /// /// Sends a message to the server over a named pipe. /// @@ -225,7 +228,7 @@ public static NamedPipeClientStream CreateAndConnectPipe(string pipeName, string private static NamedPipeClientStream CreatePipe(string pipeName,string serverName) { - return new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough); + return new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough, System.Security.Principal.TokenImpersonationLevel.None); } } } diff --git a/NamedPipeWrapper/NamedPipeConnection.cs b/NamedPipeWrapper/NamedPipeConnection.cs index 1894718..7d454e8 100644 --- a/NamedPipeWrapper/NamedPipeConnection.cs +++ b/NamedPipeWrapper/NamedPipeConnection.cs @@ -76,12 +76,12 @@ public void Open() var readWorker = new Worker(); readWorker.Succeeded += OnSucceeded; readWorker.Error += OnError; - readWorker.DoWork(ReadPipe); + readWorker.DoWork(ReadPipe, CancellationToken.None); var writeWorker = new Worker(); writeWorker.Succeeded += OnSucceeded; writeWorker.Error += OnError; - writeWorker.DoWork(WritePipe); + writeWorker.DoWork(WritePipe, CancellationToken.None); } /// diff --git a/NamedPipeWrapper/NamedPipeServer.cs b/NamedPipeWrapper/NamedPipeServer.cs index cae2bc0..fd6dec6 100644 --- a/NamedPipeWrapper/NamedPipeServer.cs +++ b/NamedPipeWrapper/NamedPipeServer.cs @@ -3,7 +3,8 @@ using System; using System.Collections.Generic; using System.IO.Pipes; - +using System.Threading; + namespace NamedPipeWrapper { /// @@ -27,7 +28,8 @@ public NamedPipeServer(string pipeName) /// Name of the pipe to listen on public NamedPipeServer(string pipeName, PipeSecurity pipeSecurity) : base(pipeName, pipeSecurity) - { + { + } } @@ -84,11 +86,20 @@ public Server(string pipeName, PipeSecurity pipeSecurity) /// This method returns immediately. /// public void Start() + { + Start(CancellationToken.None); + } + + /// + /// Begins listening for client connections in a separate background thread. + /// This method returns immediately. + /// + public void Start(CancellationToken stoppingToken) { _shouldKeepRunning = true; var worker = new Worker(); worker.Error += OnError; - worker.DoWork(ListenSync); + worker.DoWork(() => ListenSync(stoppingToken), stoppingToken); } /// @@ -139,6 +150,7 @@ public void Stop() } } + // If background thread is still listening for a client to connect, // initiate a dummy connection that will allow the thread to exit. //dummy connection will use the local server name. @@ -151,11 +163,14 @@ public void Stop() #region Private methods - private void ListenSync() + private void ListenSync(CancellationToken stoppingToken) { _isRunning = true; while (_shouldKeepRunning) { + if (stoppingToken.IsCancellationRequested) + Stop(); + WaitForConnection(_pipeName, _pipeSecurity); } _isRunning = false; @@ -276,11 +291,18 @@ public static NamedPipeServerStream CreateAndConnectPipe(string pipeName, PipeSe var pipe = CreatePipe(pipeName, pipeSecurity); pipe.WaitForConnection(); return pipe; - } + } + public static NamedPipeServerStream CreatePipe(string pipeName, PipeSecurity pipeSecurity) - { - return new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough, 0, 0, pipeSecurity); - } - } -} + { + //return new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough, 0, 0, pipeSecurity); + + // NOTE: we use the old framework version package to call into the NamedPipeServerStream constructor that allows + // PipeSecurity to be passed in. It is a known issue that .net core does not support the pipesecurity param + // as it's based upon native windows functionality and is not supported cross platform. Using the package + // is a successful workaround to set the pipe's security. + return NamedPipeServerStreamConstructors.New(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough, 0, 0, pipeSecurity); + } + } +} \ No newline at end of file diff --git a/NamedPipeWrapper/NamedPipeWrapper - Backup.csproj b/NamedPipeWrapper/NamedPipeWrapper - Backup.csproj new file mode 100644 index 0000000..5a002c9 --- /dev/null +++ b/NamedPipeWrapper/NamedPipeWrapper - Backup.csproj @@ -0,0 +1,26 @@ + + + net5.0-windows10.0.19041.0 + Library + SAK + SAK + SAK + SAK + false + + + bin\Debug\NamedPipeWrapper.XML + + + + + + + 1.0.2 + + + 4.5.1 + + + + \ No newline at end of file diff --git a/NamedPipeWrapper/NamedPipeWrapper.csproj b/NamedPipeWrapper/NamedPipeWrapper.csproj index 90ec8e9..219784e 100644 --- a/NamedPipeWrapper/NamedPipeWrapper.csproj +++ b/NamedPipeWrapper/NamedPipeWrapper.csproj @@ -1,62 +1,20 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {73152691-3CDE-46DF-8D04-7117747DFFE7} - Library - Properties - NamedPipeWrapper - NamedPipeWrapper - v4.0 - 512 - SAK - SAK - SAK - SAK - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\NamedPipeWrapper.XML - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - + + + net5.0-windows10.0.19041.0 + Library + SAK + SAK + SAK + SAK + true + + + bin\Debug\NamedPipeWrapper.XML + + + + + + + \ No newline at end of file diff --git a/NamedPipeWrapper/NamedPipeWrapper.csproj.old b/NamedPipeWrapper/NamedPipeWrapper.csproj.old new file mode 100644 index 0000000..90ec8e9 --- /dev/null +++ b/NamedPipeWrapper/NamedPipeWrapper.csproj.old @@ -0,0 +1,62 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {73152691-3CDE-46DF-8D04-7117747DFFE7} + Library + Properties + NamedPipeWrapper + NamedPipeWrapper + v4.0 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + bin\Debug\NamedPipeWrapper.XML + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NamedPipeWrapper/NamedPipeWrapper.csproj.user b/NamedPipeWrapper/NamedPipeWrapper.csproj.user new file mode 100644 index 0000000..e81ceff --- /dev/null +++ b/NamedPipeWrapper/NamedPipeWrapper.csproj.user @@ -0,0 +1,6 @@ + + + + <_LastSelectedProfileId>E:\git\undigital\named-pipe-wrapper\NamedPipeWrapper\Properties\PublishProfiles\FolderProfile.pubxml + + \ No newline at end of file diff --git a/NamedPipeWrapper/Properties/AssemblyInfo.cs b/NamedPipeWrapper/Properties/AssemblyInfo.cs index 2dae0fe..97082b1 100644 --- a/NamedPipeWrapper/Properties/AssemblyInfo.cs +++ b/NamedPipeWrapper/Properties/AssemblyInfo.cs @@ -5,12 +5,8 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Named Pipe Wrapper library")] [assembly: AssemblyDescription("A simple, easy to use, strongly-typed wrapper around .NET named pipes.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NamedPipeWrapper")] -[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyCopyright("Copyright © 2019 - 2022")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -32,5 +28,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.4.0.0")] -[assembly: AssemblyFileVersion("1.4.0.0")] +//[assembly: AssemblyVersion("1.4.0.0")] +//[assembly: AssemblyFileVersion("1.4.0.0")] diff --git a/NamedPipeWrapper/Properties/PublishProfiles/FolderProfile.pubxml b/NamedPipeWrapper/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 0000000..ebca823 --- /dev/null +++ b/NamedPipeWrapper/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,12 @@ + + + + + Release + Any CPU + bin\Release\net472\publish\ + FileSystem + + \ No newline at end of file diff --git a/NamedPipeWrapper/Properties/PublishProfiles/FolderProfile.pubxml.user b/NamedPipeWrapper/Properties/PublishProfiles/FolderProfile.pubxml.user new file mode 100644 index 0000000..a32fee2 --- /dev/null +++ b/NamedPipeWrapper/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -0,0 +1,6 @@ + + + + diff --git a/NamedPipeWrapper/Threading/Worker.cs b/NamedPipeWrapper/Threading/Worker.cs index 8d9b71b..d40f6e4 100644 --- a/NamedPipeWrapper/Threading/Worker.cs +++ b/NamedPipeWrapper/Threading/Worker.cs @@ -33,22 +33,25 @@ public Worker(TaskScheduler callbackThread) _callbackThread = callbackThread; } - public void DoWork(Action action) + public void DoWork(Action action, CancellationToken stoppingToken) { - new Task(DoWorkImpl, action, CancellationToken.None, TaskCreationOptions.LongRunning).Start(); + new Task(DoWorkImpl, Tuple.Create(action, stoppingToken), stoppingToken, TaskCreationOptions.LongRunning).Start(); } private void DoWorkImpl(object oAction) { - var action = (Action) oAction; + var tuple = (Tuple) oAction; + var action = tuple.Item1; + var stoppingToken = tuple.Item2; + try { action(); - Callback(Succeed); + Callback(Succeed, stoppingToken); } catch (Exception e) { - Callback(() => Fail(e)); + Callback(() => Fail(e), stoppingToken); } } @@ -64,9 +67,9 @@ private void Fail(Exception exception) Error(exception); } - private void Callback(Action action) + private void Callback(Action action, CancellationToken stoppingToken) { - Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, _callbackThread); + Task.Factory.StartNew(action, stoppingToken, TaskCreationOptions.None, _callbackThread); } }