Jump to content
  • Advertisement
Sign in to follow this  
jdub

Why isn't my code using Pipes working?

This topic is 1720 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to set up communication via a Named Pipe between two programs.  I am very new to the concepts behind pipes and multithreaded applications so correct me if my terminology is wrong or if I am doing something terribly.  Here's how the program is designed:  

 

My client program (C# .NET) takes strings via command line input and writes them over a named pipe to my host program (C++/Windows API).  The host program simply outputs these strings in its own command line window.

 

The problem I am having is that once I create the pipe in the host application and then startup the client application using ShellExecute(), the C# client code reports that it has connected to the Pipe successfully.  However, on my first call to ReadFile() from within my C++ code, GetLastError() reports an ERROR_NO_DATA error (which according to MSDN's minimal documentation means "The pipe is being closed."

 

Here is the client-side code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO.Pipes;

namespace PipeClient
{
    class Program
    {
        static void Main(string[] args)
        {
            using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".","testPipe"))
            {

                Console.Out.WriteLine("Attempting to connect to host...");
                pipeStream.Connect();
                Console.Out.Write(" Successful");

                while (true)
                {
                    String input = Console.In.ReadLine();

                    byte[] buff = new byte[input.Length * sizeof(char)];
                    System.Buffer.BlockCopy(input.ToCharArray(), 0, buff, 0, buff.Length);

                    pipeStream.Write(buff, 0, buff.Length);
                }
            }
        }
    }
}

Here is the Host code:

#include<iostream>
#include<Windows.h>
#include<string>

#define MAX_WINDOW_NAME_LENGTH 1024

HANDLE hConsolePipe = INVALID_HANDLE_VALUE;
HWND hWnd = NULL;

bool init(void);
void freeResources(void);

bool init(void)
{
	DWORD error;
	int result;

	//set the name of the console to a random name guaranteed to be unique so that we can retrieve the HWND with FindWindow()
	/*std::wstring newConsoleName(L"asdfasdfasdf");

	wchar_t consoleName[MAX_WINDOW_NAME_LENGTH];
	GetConsoleTitle(consoleName, MAX_WINDOW_NAME_LENGTH);
	
	SetConsoleTitle(newConsoleName.data());
	Sleep(40);

	hWnd = FindWindow(NULL, newConsoleName.data());

	SetConsoleTitle(consoleName);*/
	
	//create the pipe
	hConsolePipe = CreateNamedPipe(
							L"\\\\.\\pipe\\testPipe", 
							PIPE_ACCESS_DUPLEX,
							PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT,
							1,
							256, 
							256,
							0, 
							NULL);

	if(hConsolePipe == INVALID_HANDLE_VALUE)
	{
		OutputDebugString(L"\nfailed to create the console pipe\n");
		return false;
	}

	//launch the client
	result = (int)ShellExecute(hWnd, L"open", L"PipeClient.exe", NULL, L"C:\\Users\\Jared\\Documents\\Visual Studio 2012\\Projects\\PipeTest\\Debug\\", 1) ;
	if(result <= 32)
	{
		OutputDebugString(L"\nUnable to open 'PipeClient.exe'\n");
		return false;
	}

	while(!ConnectNamedPipe(hConsolePipe, NULL))
	{
		error = GetLastError();

		if(error == ERROR_PIPE_CONNECTED)
			break;	

		if(error != ERROR_PIPE_LISTENING)
		{
			OutputDebugString(L"\nClient-Host connection failed\n");
			return false;
		}
	}

	return true;

	/*******************
	
	while(true):
		if data is pending in the read-buffer:
			parse the data and execute the commands it contains

		if data is pending in the write-vector:
			while(write-vector is not empty):
				write data in write-vector[i] to the pipe
				remove write-data[i]

	*****************/

	//run the client app and then hook it up 
}

void freeResources(void)
{
	CloseHandle(hConsolePipe);
}

int main(void)
{
	char readBuffer[256];
	DWORD numBytesRead;
	int error = 0;

	if(!init())
	{
		freeResources();
		return 0;
	}
	
	while(1)
	{
		if(!ReadFile(hConsolePipe, readBuffer, 256, &numBytesRead, NULL)) //This is the line which causes ERROR_NO_DATA
		{
			error = GetLastError();
			if(error != ERROR_IO_PENDING)
			{
				OutputDebugString(L"\nGetLastError() != ERROR_IO_PENDING\n");
				break;
			}
		}
		else
		{
			std::cout << "\nData received:  \n\n";
			
			for(int i = 0; i < numBytesRead; i++)
			{
				std::cout << readBuffer[i];
			}

			std::cout << "\n\n";
		}
	}

	freeResources();
}

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!