2

What I want to do is have a named pipe client written in c++ to be able to communicate with a named pipe server written in C#. I have been unable to accomplish this so far.

CreateFile gives me an invalid handle value, GetLastError returns 2.

Here is the c++ part (client)

#include "stdafx.h"
#include <windows.h> 
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>

using namespace std;

#define PIPE_NAME L"\\\\.\\pipe\\TestPipe"
#define BUFF_SIZE 512

int main()
{
    HANDLE hPipe;

    hPipe = CreateFile(PIPE_NAME, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);

    if (hPipe == INVALID_HANDLE_VALUE)
    {
        cout << "INVALID_HANDLE_VALUE" << GetLastError() << endl;
        cin.get();
        return -1;
    }

    cout << hPipe << endl;

    DWORD mode = PIPE_READMODE_MESSAGE;

    SetNamedPipeHandleState(hPipe, &mode, nullptr, nullptr);

    bool success = false;
    DWORD read;

    while(true)
    {
        TCHAR chBuff[BUFF_SIZE];
        do
        {
            success = ReadFile(hPipe, chBuff, BUFF_SIZE*sizeof(TCHAR), &read, nullptr);
        } while (!success);

        _tprintf(TEXT("\"%s\"\n"), chBuff);
    }
}

And here is the server

using System;
using System.IO.Pipes;
using System.Text;

namespace BasicServer
{

    public static class Program
    {
        private static NamedPipeServerStream _server;

        static void Main(string[] args)
        {
            _server = new NamedPipeServerStream(@"\\.\pipe\TestPipe", PipeDirection.Out, 1, PipeTransmissionMode.Message);
            _server.WaitForConnection();
            Console.WriteLine(_server.IsConnected);
            Console.WriteLine("Client connected\n Sending message");
            byte[] buff = Encoding.UTF8.GetBytes("Test message");
            _server.Write(buff, 0, buff.Length);
            while (true)
            {
                Console.ReadKey();
                Console.Write("\b \b");
            }
        }
    }
}

I have been able to connect with a client written in C# but the c++ -> C# communication should be possible as far as I know.

Here was my test client I wrote in c#, which works

using System;
using System.IO.Pipes;
using System.Text;

namespace BasicClientC
{

    public class Program
    {
        private static NamedPipeClientStream client;

        static void Main(string[] args)
        {
            client = new NamedPipeClientStream(@".", @"\\.\pipe\TestPipe", PipeDirection.In);
            client.Connect();
            byte[] buffer = new byte[512];
            client.Read(buffer, 0, 512);
            Console.WriteLine(Encoding.UTF8.GetString(buffer));
            Console.ReadKey();
        }
    }
}

So where is my mistake?

crayzeewulf
  • 5,840
  • 1
  • 27
  • 30

1 Answers1

2

I know why.

  1. When creating your pipe in C#, use just "TestPipe" as the name of the pipe, don't include \\.\pipe\ as a prefix for this pipe's name.

  2. From C++, use the full path to the pipe: "\\.\pipe\TestPipe". Your C++ logic doesn't need a change for this, as you have defined it just fine: L"\\\\.\\pipe\\TestPipe"

This may help, as well. Funny enough, I ran into this three years ago or more, and now its all coming back to me.

Community
  • 1
  • 1
Alexandru
  • 12,264
  • 17
  • 113
  • 208
  • Ok you solved the connection problem but I get this now, prolly not interpreting it correctly I think :S https://i.gyazo.com/77ec6b69d14aec6ad7a0cc3f5168f8fe.png where the 0xA0 is the value of the HANDLE hPipe –  Oct 14 '15 at 19:51
  • @HyunMi I noticed you use `TCHAR` in your C++ logic. Does your application target Unicode characters? – Alexandru Oct 14 '15 at 19:53
  • Yes, I just forgot to change it in my test server, :S sorry –  Oct 14 '15 at 19:54
  • 1
    @HyunMi If you're sending Unicode characters across the pipe, you may need to change your font in Command Prompt's settings in order to view them. Check this out for more details: http://stackoverflow.com/questions/22578567/passing-a-stringstream-to-console-output-in-unicode-project – Alexandru Oct 14 '15 at 19:56