第一种为FILE *_popen( const char *command, const char *mode); 第一个参数直接传命令,返回端直接为管道的句柄,用fget来提取文件信息。
贴出关键代码:
WideCharToMultiByte(CP_ACP, 0, strCmmdLine.GetBuffer(), strCmmdLine.GetLength(), path, MAX_PATH-1, NULL, NULL);
//注意,命令行参数必须为ASCII字符
if( (child_output = _popen(path, "rt" )) == NULL )
return 1;
while(!feof( child_output ) )
{
if( fgets( psBuffer, 1023, child_output ))
{
// 将子进程的标准输出写入管道,提供给自己的父进程
// 格式是先写数据块长度(0表示结束),再写数据块内容
pInfo->strRes += psBuffer;
}
}
// 写“0”表示所有数据都已写完
return _pclose( child_output );
第二种较为复杂,但设置上可有多种选择,如开启子进程后可选择将子进程隐藏显示
创建管道原型函数,目的就是开启一个匿名管道,同时获取到管道的读写句柄
BOOL WINAPI CreatePipe( __out PHANDLE hReadPipe, __out PHANDLE hWritePipe, __in LPSECURITY_ATTRIBUTES lpPipeAttributes, __in DWORD nSize );
传命令行函数
CreateProcess()
关键代码:
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE; //注意,这一行一定要为TRUE,子进程可以继承句柄设置
saAttr.lpSecurityDescriptor = NULL;
if(!CreatePipe(&(pInfo->hRead), &(pInfo->hWrite),&saAttr,0))
{
return 1;
}
STARTUPINFO siStartInfo;
GetStartupInfo(&siStartInfo); //通过这个函数省了不少事
siStartInfo.hStdOutput = pInfo->hWrite; //设置输出句柄
siStartInfo.hStdError = pInfo->hWrite; //设置错误句柄
siStartInfo.cb = sizeof(STARTUPINFO); //设置大小
siStartInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
siStartInfo.wShowWindow = SW_HIDE;
PROCESS_INFORMATION piProcInfo;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
CString strCmmdLine;
strCmmdLine = "E:\\TestLoad.exe ";
CreateProcess(NULL, //第一个参数可为空,
strCmmdLine.GetBuffer(),
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
char buf[1024] = {0};
DWORD len;
CloseHandle(pInfo->hWrite); //注意,一定要在本端关闭句柄,否则子进程无法进行写操作
while(ReadFile(pInfo->hRead, buf, 1023, &len, NULL))
{
pInfo->strRes += buf;
}