简体   繁体   中英

How to communicate C and C# programs using named pipes

I have 2 executables, one in C and one in C# and want them to communicate via a named pipe.
The C# app waits for a connection but never gets one
The C app attempts to create a pipe but always gets ERROR_PIPE_BUSY
I'm obviously doing something wrong but cannot see it.

C# code

   public partial class MainWindow : Window
    {
        private NamedPipeServerStream pipeServer;

        public MainWindow()
        {
            InitializeComponent();
            pipeServer = new NamedPipeServerStream("TestPipe", PipeDirection.In);
            Debug.WriteLine("waiting");
            pipeServer.WaitForConnection();
            Debug.WriteLine("Connected");
        }
    }

C code

   while (1)
   {
       _pipe = CreateNamedPipe(pipename,
         PIPE_ACCESS_OUTBOUND,
         PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,   // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
         1,
         1024 * 16,
         1024 * 16,
         NMPWAIT_USE_DEFAULT_WAIT,
         NULL);
   // Break if the pipe handle is valid. 

      int err = GetLastError();
      printf("created pipe %d\n", err);
      if (_pipe != INVALID_HANDLE_VALUE)
         break;

      // Exit if an error other than ERROR_PIPE_BUSY occurs. 

      if (err != ERROR_PIPE_BUSY)
      {
         printf("Could not open pipe. GLE=%d\n", GetLastError());
         exit(-1);
      }

      // All pipe instances are busy, so wait for 20 seconds. 

      if (!WaitNamedPipe(pipename, 20000))
      {
         printf("Could not open pipe: 20 second wait timed out.");
         exit(-1);
      }
   }

What is my error

You have to set the access rights when creating the pipe in order to overcome the access denied message

PipeSecurity CreateSystemIOPipeSecurity()
{
    PipeSecurity pipeSecurity = new PipeSecurity();

     var id = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);

    // Allow Everyone read and write access to the pipe. 
    pipeSecurity.SetAccessRule(new PipeAccessRule(id, PipeAccessRights.ReadWrite, AccessControlType.Allow));

    return pipeSecurity;
}

public MainWindow()
{
    InitializeComponent();
    PipeSecurity ps = CreateSystemIOPipeSecurity();
    pipeServer = new NamedPipeServerStream(
        "TestPipe", 
        PipeDirection.InOut,
        1,
        PipeTransmissionMode.Byte,
        PipeOptions.Asynchronous,
        512,
        512,
        ps,
        System.IO.HandleInheritability.Inheritable);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM