We are implementing interprocess communications using Named Pipes.
If I use a console application for both the NamedPipeClientStream
and the NamedPipeServerStream
it works beautifully. But when I move the server stream to a Windows service the client console application throws an UnauthorizedAccessException
('Access to the path is denied.') when the NamedPipedClientStream
tries to connect.
The code to initialize both ends of the communication:
On the client console application:
_clientStream = new NamedPipeClientStream(".", pipeName,
PipeDirection.InOut, PipeOptions.None,
TokenImpersonationLevel.Impersonation);
On the server Windows service:
_server = new NamedPipeServerStream(pipeName,
PipeDirection.InOut, maxNumberOfServerInstances: 1);
EDIT:
This seems to be a known problem up to at least Net 5. The problem is that you need extra security permissions server (Windows service) side that must be added to the constructor. But Net.Core and later do not provide such a constructor! Adding the permissions later by calling
namedPipedServerStream.SetAccessControl
does not seem to work.
A Nuget package from a fellow developper supposedly solves it, but it seems incompatible with Net 8 for now.
The solution: implement in Net Framework...
I solved it: You need the Nugetpackage: NamedPipeServerStream.NetFrameworkVersion Use it thus:
using System.IO.Pipes;
var pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule(new
SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
PipeAccessRights.ReadWrite, AccessControlType.Allow));
using var serverStream = NamedPipeServerStreamConstructors.New(pipeName,
PipeDirection.InOut, 1, PipeTransmissionMode.Byte,
PipeOptions.Asynchronous | PipeOptions.WriteThrough, 0, 0,
pipeSecurity);