一个简单的使用Pipe和thread的例子

目的很简单,仅仅是使用createprocess创建cmd并使用pipe和其进行通信,双向管道,既能写入消息又能得到回复的信息

#include "stdafx.h"
#include "windows.h"
#include "process.h"
#include "iostream"
using namespace std;

#define THREAD_NUM 2
#define CLOSEHANDLE(h)	if (h)	\
{								\
	CloseHandle(h);				\
}								\


HANDLE hReadPipe1, hWritePipe1, hReadPipe2, hWritePipe2;
HANDLE handle[THREAD_NUM];
DWORD  byteRead, byteWrite;
string write_message;

unsigned int __stdcall ThreadWritePipe(PVOID pData)
{
	//进程的输入重定向到hReadPipe2,所以从hWritePipe2写入
	while (true)
	{
		if (!write_message.empty())
		{
			write_message += "\r\n";
			if (!WriteFile(hWritePipe2, (LPCVOID)write_message.c_str(), write_message.length(), &byteWrite, NULL))
			{
				return 1;
			}
			else
			{
				write_message = "";
			}
		}
		Sleep(100);
	}
	return 0;
}

unsigned int __stdcall ThreadReadPipe(PVOID pData)
{
	BYTE buffer[1024];
	while(true)
	{
		RtlZeroMemory(buffer,1024);
		//进程的输出重定向到hWritePipe1,所以从hReadPipe1读取
		if(ReadFile(hReadPipe1,buffer,1023,&byteRead,NULL) == NULL)
		{
			break;
		}
		else
		{
			cout << buffer;
		}
		Sleep(100);
	}
	return 0;
}

bool CreateReadWritePipe()
{
	SECURITY_ATTRIBUTES sat;
	sat.nLength				= sizeof(SECURITY_ATTRIBUTES);
	sat.bInheritHandle		= true;
	sat.lpSecurityDescriptor= NULL;
	//创建管道,它用来做子进程的输出
	if(!CreatePipe(&hReadPipe1, &hWritePipe1, &sat, NULL))
	{
		cout << ("Create Pipe1 Error!") << endl;
		return false;
	}

	//创建管道,它用来做子进程的输入
	if(!CreatePipe(&hReadPipe2, &hWritePipe2, &sat, NULL))
	{
		cout << "Create Pipe2 Error!" << endl;
		return false;
	}
	return true;
}

bool CreateChildProcess()
{
	STARTUPINFO			startupinfo;
	PROCESS_INFORMATION pinfo;

	string	exe_parth = "C:\\Windows\\System32\\cmd.exe";

	startupinfo.cb = sizeof(STARTUPINFO);
	//用GetStartupInfo获得当前进程的参数,否则STARTUPINFO参数太多,会让人抓狂
	GetStartupInfo(&startupinfo);
	startupinfo.hStdInput   = hReadPipe2;
	startupinfo.hStdError   = hWritePipe1;
	startupinfo.hStdOutput  = hWritePipe1;
	//要有STARTF_USESTDHANDLES,否则hStdInput, hStdOutput, hStdError无效
	startupinfo.dwFlags	    = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	startupinfo.wShowWindow = SW_HIDE;

	if(!CreateProcess(NULL, (char*)exe_parth.c_str(), NULL, NULL, TRUE, NULL, NULL, NULL, &startupinfo, &pinfo))
	{
		cout << ("create process error!") << endl;
		return false;
	}
	return true;
}

bool Init()
{
	if (!CreateReadWritePipe())
	{
		return false;
	}
	if (!CreateChildProcess())
	{
		return false;
	}

	//定义四个句炳保留两个管道的信息
	handle[0] = (HANDLE)_beginthreadex(0, 0, ThreadWritePipe, 0, 0, 0);
	handle[1] = (HANDLE)_beginthreadex(0, 0, ThreadReadPipe,  0, 0, 0);

	return true;
}

void Execute()
{
	char str[1024] = {'\0'};
	bool flag = true;
	while(flag)
	{
		gets(str);
		if (str[0] == 'q')
		{
			flag = !flag;
			write_message += "exit";
		}
		else
		{
			write_message += str;
		}
		Sleep(100);
	}
}

void EndAndClearup()
{
	CLOSEHANDLE(hReadPipe1);
	CLOSEHANDLE(hReadPipe2);
	CLOSEHANDLE(hWritePipe1);
	CLOSEHANDLE(hWritePipe2);

//	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
}

int main(int argc, char** argv)
{
	if (Init())
	{
		Execute();

		EndAndClearup();
	}

	return 0;
}

代码风格写得并不怎么好。。也没太在意使用class就用了cpp。。主要是给大家个同时使用thread额pipe的demo

你可能感兴趣的:(一个简单的使用Pipe和thread的例子)