Jump to content

  • Log In with Google      Sign In   
  • Create Account


Why isn't my code using Pipes working?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
No replies to this topic

#1 jdub   Members   -  Reputation: 411

Like
0Likes
Like

Posted 04 January 2014 - 02:37 AM

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

J.W.

Sponsor:



Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS