-->

How do I make named pipes work between c++ and .NE

2019-04-13 23:30发布

问题:

I just had a really tough time making Named Pipes work between c++ and .NET. I had no problems creating Named Pipes that worked between 2 c++ apps, or between 2 .NET apps.

回答1:

I dont have problem with this communication, i use this scenario in some project.

C++ side:

LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\pipename");
CHAR chReadBuf[1024];
DWORD cbRead;
BOOL fResult;  

fResult = CallNamedPipe( 
    lpszPipename,          // pipe name 
    _Message,              // message to server 
    strlen(_Message),      // message length 
    chReadBuf,             // buffer to receive reply 
    sizeof(chReadBuf),     // size of read buffer 
    &cbRead,               // number of bytes read 
    NMPWAIT_WAIT_FOREVER); // wait;-) 

At C# side:

    public string GetMessageFromPipe()
    {
        int _lenght = 0;

        /*
         * Pipe Control Block
         */
        _pipeserver.WaitForConnection();

        do
        {
            _lenght += _pipeserver.Read(_buffer, _lenght, _buffer.Length);
        }
        while (!_pipeserver.IsMessageComplete);

        _pipeserver.Disconnect();
        /*
         * End of Pipe Control Block
         */

        if (_lenght == 0)
        {
            throw new ArgumentException("Message is empty ;-(");
        }

        return Encoding.UTF8.GetString(_buffer, 0, _lenght);
    }

Pipe Creation:

_pipeserver = new NamedPipeServerStream("pipename",
  PipeDirection.InOut, 254, PipeTransmissionMode.Message,
  PipeOptions.Asynchronous, 262144, 262144);


回答2:

I found that I could use ProcessExplorer to see the names of the pipes that I was opening. Even though I used the exact same name in both c++ and .NET, ProcessExplorer showed that they were different.

I ended up using these names: In .NET: "\\.\pipe\XXXDebug"

In c++: "\\.\pipe\pipe\XXXDebug"

What I saw in ProcessExplorer for both of these was: \Device\NamedPipe\pipe\XXXDebug

One more thing, I opened the pipe in .NET via:

NamedPipeServerStream pipe = new NamedPipeServerStream(_pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte);

And I opened the pipe in c++ via:

    g_hPipe = CreateFile(
        _pipeName,
        GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);