Reputation:
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?
Upvotes: 2
Views: 6646
Reputation: 12932
I know why.
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.
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.
Upvotes: 2