请高手帮忙:如何读取管道?

24ge 2003-12-18 10:51:54
我看了一篇vc关于管道的帖子,我想将dos窗口显示的内容通过管道显示到memo中,以下程序创建管道和进程成功,并已经写入管道,但是读不出来。请高手帮忙看看:

HANDLE hRead,hWrite;
SECURITY_ATTRIBUTES sa;
AnsiString appname=".\\masm5\\masm clu.asm";

sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0))
{
ShowMessage("Fatal Error: Create pipe error!");
return;
}

STARTUPINFO si;
PROCESS_INFORMATION pi;

si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_SHOW; //hide
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

if (!CreateProcess(NULL,appname.c_str(),NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
ShowMessage("Error on CreateProcess()");
return;
}

CloseHandle(hWrite);

char buffer[4096];
DWORD bytesRead;

while (true)
{
if (ReadFile(hRead,&buffer,4096,&bytesRead,NULL) == NULL)
break;
Memo1->Text += buffer;
Application->ProcessMessages();
Sleep(200);
}
...全文
74 点赞 收藏 5
写回复
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
HUANG_JH 2003-12-18
BCB的WINTOOLS范例

// read from the pipe and put in richedit
assert(hReadPipe);
DWORD BytesRead; //unsigned long
char dest[4000];
bool RdLoopDone = false;
ResultsRE->Lines->Clear();
FBreak = 1;
if (ExitCode) Screen->Cursor = crDefault;
while (!RdLoopDone) {
memset(dest, 0, 4000);
assert(ReadFile(hReadPipe, &dest, sizeof(dest), &BytesRead, NULL));
ResultsRE->Lines->Add(String(dest));
if (BytesRead < 4000) RdLoopDone = true;
if (FBreak > 150) RdLoopDone = true;
FBreak++;
}
ResultsRE->Lines->Add("FINISHED!");
回复
constantine 2003-12-18
学习
回复
短歌如风 2003-12-18
不好意思,弄错了,我说的是CreateNamedPipe,CreatePipe我没用过。我很少用无名系统对象,一般都用命名对象进行跨进程的数据交换。
我觉得CreatePipe这个函数很奇怪,如果就是可以用hwrite写并用hread读的话,没有指明管道方向,也不知道如何创建双向管道。用CreateNamedPipe创建的双向管道可以让管道两端都可以向管道写并从管道中读出另一端写的数据,不会发生干扰(相当于两个管道),也就是说,你不会读出自己写的数据。方法就是一端用CreateNamedPipe创建句柄,另一端用CreateFile创建句柄。
回复
短歌如风 2003-12-18
CreatePipe返回的两个句柄都是给你的主进程用的,分别用于读子进程的输出和向子进程输入;传给子进程的应该是CreatePipe之后用CreateFile创建。
下面是我以前用Delphi写的类似代码,是可以用的,你自己改一下吧:
procedure TMainForm.FormCreate(Sender: TObject);
var
StInfo:TStartupInfo;
PrInfo:TProcessInformation;
SecAttr: TSecurityAttributes;
begin
FPipeName := Format('\\.\pipe\InPipe%x_%x',[GetCurrentProcessId,Round(Time*24*3600)]);
hPipe := CreateNamedPipe(PChar(FPipeName), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE or PIPE_NOWAIT,
PIPE_UNLIMITED_INSTANCES, 4096, 4096,100,nil);
SecAttr.nLength := Sizeof(SecAttr);
SecAttr.lpSecurityDescriptor := nil;
SecAttr.bInheritHandle := True;
ZeroMemory(@StInfo,Sizeof(StInfo));
StInfo.cb := Sizeof(StInfo);
StInfo.dwFlags := STARTF_USESTDHANDLES;
hStd := CreateFile(PChar(FPipeName),GENERIC_WRITE or GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE,@SecAttr,
OPEN_EXISTING,0,0);
StInfo.hStdInput := hStd;
StInfo.hStdOutput := hStd;
StInfo.hStdError := StInfo.hStdOutput;
FlushConsoleInputBuffer(hStd);
CreateProcess('c:\winnt\system32\cmd.exe', nil, nil, nil, True,
CREATE_NO_WINDOW
, nil, nil,StInfo,PrInfo);
With TCmdThread.Create(PrInfo.hProcess) do
OnTerminate := CmdEnd;
TOutPutThread.Create(memoInfo,hPipe);
end;
回复
书生 2003-12-18
学习.
回复
发动态
发帖子
Windows SDK/API
创建于2007-08-02

1202

社区成员

C++ Builder Windows SDK/API
申请成为版主
社区公告
暂无公告