Как общаться на C и C # программах, используя именованные каналы - PullRequest
1 голос
/ 22 октября 2019

У меня есть 2 исполняемых файла, один на C и один на C #, и я хочу, чтобы они общались через именованный канал.
Приложение C # ожидает подключения, но никогда не получает один
Приложение C пытается создать канално всегда получает ERROR_PIPE_BUSY
Я, очевидно, делаю что-то не так, но не вижу этого.

C # код

   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 код

   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);
      }
   }

В чем моя ошибка

1 Ответ

1 голос
/ 22 октября 2019

Вы должны установить права доступа при создании канала

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);
...