关于控制台重定向!问题解决立刻结贴!

yuanhen 2003-05-31 01:50:56
我需要把控制台程序的输出结果重定向到TMemo中。
下面是参考MSDN和其他一些资料写的,但是存在一些问题:
1. 程序不够简练
2. 能不能不让控制台显示出来。我的程序每次在执行时都会产生一个可见的控制台(虽然是一闪而过)。
我对重定向的过程和步骤仍然不是很清楚,望高手指点。
void __fastcall TForm1::SetChildHandles()
{
//TODO: Add your source code here
AllocConsole();
// 保存原始标准句柄
//HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);

SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.bInheritHandle = true;
sa.lpSecurityDescriptor = NULL;

if(!CreatePipe(&hParentTemp, &hChildStdOut, &sa, 0))
Application->MessageBoxA("Create pipe error", "error", MB_OK);
DuplicateHandle(GetCurrentProcess(), hParentTemp,
GetCurrentProcess(), &hParentStdout,
0, false,
DUPLICATE_SAME_ACCESS + DUPLICATE_CLOSE_SOURCE);
SetStdHandle(STD_OUTPUT_HANDLE, hChildStdOut);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
SetChildHandles();
PROCESS_INFORMATION piChild;
STARTUPINFO Startupinfo;

GetStartupInfo(&Startupinfo);

Startupinfo.dwFlags = STARTF_USESTDHANDLES;
Startupinfo.wShowWindow = SW_HIDE;
Startupinfo.cb = sizeof(Startupinfo);

Startupinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
Startupinfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
Startupinfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);

CreateProcess(NULL, "NETSTAT -a -n",
NULL, NULL,
true, 0,
NULL, NULL,
&Startupinfo, &piChild);
WaitForSingleObject(piChild.hProcess, INFINITE);

AnsiString sOutput, sItem;
char sBuf[4097];
memOutput->Clear();
memOutput->Text = sBuf;

do
{
ReadFile(hParentStdout, sBuf, 4096, &dwRead, NULL);

sOutput += sBuf;
while(sOutput.Pos('\n')>0)
{
sItem = sOutput.SubString(1, sOutput.Pos('\n')-1);
sOutput.Delete(1, sOutput.Pos('\n'));
memOutput->Lines->Add(sItem);
}
}while(dwRead>=4096);
CloseHandle(piChild.hProcess);
FreeConsole();
}
...全文
293 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuanhen 2003-06-01
  • 打赏
  • 举报
回复


结贴了!
yuanhen 2003-06-01
  • 打赏
  • 举报
回复
好啦!问题已经解决了。解决方法参考MSDN HOWTO: Spawn Console Processes with Redirected Standard Handles(Q190351)我是在网上的MSDN找到的,我硬盘上的MSDN没有这篇文章。
我把自己的文章贴出来给需要的人做个参考吧!其实实现方法还有几种,但我的方法我认为很简单。(注:1 未看到声明的变量为全局变量 2 很多的API调用没有写注释,自己查MSDN吧 3 程序没有完全优化,有些变量可以省略)
void __fastcall TForm1::SetChildHandles()
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.bInheritHandle = true;
sa.lpSecurityDescriptor = NULL;
// 创建匿名管道(读,写)
if(!CreatePipe(&hParentTemp, &hChildStdOut, &sa, 0))
Application->MessageBoxA("Create pipe error", "error", MB_OK);
// 设置读写管道的进程
DuplicateHandle(GetCurrentProcess(), hParentTemp,
GetCurrentProcess(), &hParentStdout,
0, false,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

SetStdHandle(STD_OUTPUT_HANDLE, hChildStdOut);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
SetChildHandles();
PROCESS_INFORMATION piChild;
STARTUPINFO Startupinfo;

GetStartupInfo(&Startupinfo);
// IMPORTANT!!!!!!!!!!!!!!!!!!
Startupinfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
Startupinfo.wShowWindow = SW_HIDE;
Startupinfo.cb = sizeof(Startupinfo);
Startupinfo.hStdOutput = hChildStdOut; // KEY!!!!!!!

CreateProcess(NULL, "NETSTAT -a -n",
NULL, NULL,
true, 0,
NULL, NULL,
&Startupinfo, &piChild);
WaitForSingleObject(piChild.hProcess, INFINITE);

AnsiString sOutput, sItem;
char sBuf[4097];
memOutput->Clear();
do
{
ReadFile(hParentStdout, sBuf, 4096, &dwRead, NULL);
memOutput->Text = memOutput->Text + sBuf;
}while(dwRead>=4096);
}
yuanhen 2003-05-31
  • 打赏
  • 举报
回复



我把问题简化一下吧!
怎么屏蔽掉调用AllocConsole()时出现的控制台窗口!但是必须保留STD_OUTPUT_HANDLE.
nnfish 2003-05-31
  • 打赏
  • 举报
回复
学习。。
sprewellkobe 2003-05-31
  • 打赏
  • 举报
回复
帮你顶一下!
yuanhen 2003-05-31
  • 打赏
  • 举报
回复


难道每人做过吗?

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧