如何使用命名管道通信 C 和 C# 程序

Posted

技术标签:

【中文标题】如何使用命名管道通信 C 和 C# 程序【英文标题】:How to communicate C and C# programs using named pipes 【发布时间】:2019-10-22 13:29:08 【问题描述】:

我有 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);
      
   

我的错误是什么

【问题讨论】:

对于客户端管道,使用CreateFile 而不是CreateNamedPipe 谢谢,但现在我收到 ERROR_ACCESS_DENIED pipename 是 UNC 路径吗?例如:\\.\pipename。你怎么称呼CreateFile?应该是:CreateFile(pipename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 管道名称定义为LPTSTR pipename = L"\\\\.\\pipe\\TestPipe" 根据您的评论创建文件 我用 2 个控制台应用程序对其进行了测试,效果很好。也许尝试以管理员身份运行。另外,这两个程序是否在同一台计算机上运行? pastebin.com/XqurmLKh 【参考方案1】:

您必须在创建管道时设置访问权限以克服拒绝访问消息

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

【讨论】:

以上是关于如何使用命名管道通信 C 和 C# 程序的主要内容,如果未能解决你的问题,请参考以下文章

使用命名管道的两种 C++ 到 C# 通信

C - 在顶层和底层进程之间进行通信

命名管道 C# 服务器 C++ .dll 客户端不工作?

在 Windows 7 中使用 VC++ 和 C# 中的 MemoryMappedFiles 或命名管道进行进程间通信

如何使两个进程通信?

c# c++通信--命名管道通信