1

I'm trying to receive and send messages with another process using NamedPipeServerStream. The platform I am developing on is UWP (Microsoft.NETCore.UniversalWindowsPlatform version 6.2.11).

My first attempt is the following:

using (NamedPipeServerStream pipe = new NamedPipeServerStream(
            "DynamicCabPipe",
            PipeDirection.InOut,
            10,
            PipeTransmissionMode.Byte,
            PipeOptions.Asynchronous,
            32,
            32)) {...}

Which results in

System.UnauthorizedAccessException: 'Access to the path is denied'

After some research I found this solution: How to set PipeSecurity of NamedPipeServerStream in .NET Core

var pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.ReadWrite, AccessControlType.Allow));
using (NamedPipeServerStream pipe = NamedPipeServerStreamConstructors.New(
            "DynamicCabPipe",
            PipeDirection.InOut,
            10,
            PipeTransmissionMode.Byte,
            PipeOptions.Asynchronous,
            32,
            32, pipeSecurity)) { ... }

Which results in

System.Resources.MissingManifestResourceException: 'Could not find any resources appropriate for the specified culture or the neutral culture.  Make sure "System.Core.resources" was correctly embedded or linked into assembly "NamedPipeServerStream.NetFrameworkVersion" at compile time, or that all the satellite assemblies required are loadable and fully signed.'

Now I'm stuck. Suggestions?

vuoriov4
  • 79
  • 1
  • 7
  • Pipes are subjected to the sandbox rules of a UWP app. Specifically, it will always reject an attempt to setup a pipe between two processes. So "access denied" is the expected outcome. – Hans Passant Dec 08 '20 at 10:45
  • Hi [vuoriov4](https://stackoverflow.com/users/8150295/vuoriov4), I am currently facing this problem. Did you find some workaround for this issue that you could share or do you have any suggestion to go ahead? – Juan Carlos Mar 17 '21 at 14:07
  • 1
    My "workaround" was to ditch UWP and the sandbox rules that come with it. – vuoriov4 Mar 18 '21 at 17:34

1 Answers1

0

Hello vuoriov4, I found a way to create a NamedPipeServerStream in a UWP application. I made that importing and using the native C++ function CreateNamedPipe in the UWP application. Here I put the code I used with my own data.

    // This class is in App.xaml.cs file
    sealed partial class App : Application
    {
        // DLL where the C++ function is
        [DllImport("kernel32.dll", SetLastError = true)]
        // C++ function
        static extern IntPtr CreateNamedPipe(string lpName, uint dwOpenMode,
           uint dwPipeMode, uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize,
           uint nDefaultTimeOut, IntPtr lpSecurityAttributes);

        // C++ variables to create the handle for the Named Pipe 
        static uint PIPE_ACCESS_DUPLEX = 0x00000003;
        static uint PIPE_TYPE_BYTE = 0x00000000;
        static uint PIPE_READMODE_BYTE = 0x00000000;
        static uint PIPE_WAIT = 0x00000000;
        static uint PIPE_UNLIMITED_INSTANCES = 255;

        // ... here is the class' other code ...

        // Method that return the NamedPipeServerStream that is created
        private NamedPipeServerStream GetNamedPipe()
        {
            // Named Pipe handle
            var pipe = CreateNamedPipe(
                @"\\.\pipe\LOCAL\pipeName",     // pipe name
                PIPE_ACCESS_DUPLEX,             // read/write access
                PIPE_TYPE_BYTE |                // byte type pipe 
                PIPE_READMODE_BYTE |            // byte-read mode 
                PIPE_WAIT,                      // blocking mode
                PIPE_UNLIMITED_INSTANCES,       // max. instances
                16000,                          // output buffer size
                16000,                          // input buffer size
                0,                              // client time-out 
                IntPtr.Zero);                   // default security attribute 

            if (pipe.ToInt32() == -1)
            {
                int errorNumber = Marshal.GetLastWin32Error();
                Debug.WriteLine("GetLastWin32Error: " + errorNumber.ToString());
            }
            else
            {
                try
                {
                    var safeHandle = new Microsoft.Win32.SafeHandles.SafePipeHandle(pipe, true);
                    NamedPipeServerStream pipeServer = new NamedPipeServerStream(PipeDirection.InOut, false, false, safeHandle);
                    return pipeServer;
                }
                catch (Exception exc)
                {
                    Debug.WriteLine("Error launched: " + exc.Message);
                }

            }

            return null;
        }
    } 
Juan Carlos
  • 131
  • 1
  • 6