如果在Win32应用中启动一个控制台应用, 并希望能够获取其输出内容 (如果它向stdout输出的话), 可以使用匿名管道(anonymous pipe) 将其输出重定向。下面做了一个将stdout弄到一个TMemo里的例子,是BCB做的。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//为控制台标准输出创建管道
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES));
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=true;
sa.lpSecurityDescriptor=NULL;
HANDLE ReadPipeHandle;
HANDLE WritePipeHandle; // 这里没有用到写管道
if(!CreatePipe(&ReadPipeHandle,&WritePipeHandle,&sa,0))
RaiseLastWin32Error();
//创建控制台程序进程
STARTUPINFO si;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow=SW_HIDE;
si.hStdOutput=WritePipeHandle;
si.hStdError=WritePipeHandle;
PROCESS_INFORMATION pi;
ZeroMemory(π,sizeof(PROCESS_INFORMATION));
//这里启动console程序
if(!CreateProcess("YourProgram.exe",NULL,NULL,NULL,true,0,NULL,NULL,&si,π))
RaiseLastWin32Error();
//读管道
char Data[1024];
while(true)
{
DWORD BytesRead;
DWORD TotalBytes;
DWORD BytesLeft;
//检查管道数据
if(!PeekNamedPipe(ReadPipeHandle,Data,sizeof(Data),&BytesRead,
&TotalBytes,&BytesLeft))RaiseLastWin32Error();
//有数据的话就读取
if(BytesRead)
{
if(!ReadFile(ReadPipeHandle,Data,sizeof(Data)-1,&BytesRead,NULL))
RaiseLastWin32Error();
Data[BytesRead]='\0';
//写TMemo
Memo1->Lines->Add(AnsiString(Data));
}
else
{
//判断控制台程序是否结束
if(WaitForSingleObject(pi.hProcess,0)==WAIT_OBJECT_0)break;
}
ProcessMessages();
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(ReadPipeHandle);
CloseHandle(WritePipeHandle);
}
以上是网上看到的····不知道有没有用··
偶是真的白菜········· |