如何重定向DOS窗口里的输出内容至我的程序界面里?

incats 2006-11-13 12:27:13
用CreateProcess 调用了一个DOS下的命令,希望将它运行中的所有提示信息都在我的界面里反应。如何实现? 改变了CreateProcess里的StartupInfo那一选项也不行。
BOOL CMyTestDlg::RunAndRedirectOutput(CString CommandLine, CString OutputFile)
{
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
SECURITY_ATTRIBUTES SecAtrrs;
HANDLE hAppProcess, hAppThread, hOutputFile;

TRY
{
memset(&SecAtrrs, 0, sizeof(SecAtrrs));
SecAtrrs.nLength = sizeof(SecAtrrs);
SecAtrrs.lpSecurityDescriptor = NULL;
SecAtrrs.bInheritHandle = TRUE;

hOutputFile = CreateFile( (LPCTSTR)OutputFile,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
&SecAtrrs,
CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY,
0);

if (hOutputFile != INVALID_HANDLE_VALUE)
{
memset(&StartupInfo, 0, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.dwFlags = NULL;//STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
StartupInfo.wShowWindow = SW_NORMAL; //HIDE;
StartupInfo.hStdOutput = hOutputFile;
StartupInfo.hStdError = hOutputFile;

if(CreateProcess(NULL,
(LPTSTR)(LPCTSTR)CommandLine,
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE|REALTIME_PRIORITY_CLASS,
NULL,
NULL,
&StartupInfo,
&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
hAppProcess = ProcessInfo.hProcess;
hAppThread = ProcessInfo.hThread;
}
}
}
CATCH(CException, e)
{
char lpError[1000];
int nMaxError = 1000;
e->GetErrorMessage(lpError, nMaxError);
MessageBox(lpError);
}
END_CATCH

if (hOutputFile) CloseHandle(hOutputFile);
if (hAppThread) CloseHandle(hAppThread);
if (hAppProcess) CloseHandle(hAppProcess);

return TRUE;

}
...全文
367 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
mynamelj 2006-11-13
  • 打赏
  • 举报
回复
BOOL ReadConsoleOutputCharacter(
HANDLE hConsoleOutput,
LPTSTR lpCharacter,
DWORD nLength,
COORD dwReadCoord,
LPDWORD lpNumberOfCharsRead
);
HuWenjin 2006-11-13
  • 打赏
  • 举报
回复
用命名管道

网上有现成的例子
hslinux 2006-11-13
  • 打赏
  • 举报
回复
笨办法:aa.exe >> aa.txt,,先输出到文件,再读文件显示出来。。。。。。
CUG122032 2006-11-13
  • 打赏
  • 举报
回复
自己做一个DOS虚拟机
HuWenjin 2006-11-13
  • 打赏
  • 举报
回复
入口参数是一个DOS命令,执行完成后,从通道中读取出显示内容,显示到对话框的编辑窗内
void CKeyAssDlg::ExecuteUserCommand(LPCTSTR lpszCmd)
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
CString strCmdInfo;
char buffer[10240] = {0};
DWORD bytesRead = 0;
DWORD dwRead = 0 ;
char szCmd[256];
int nLen = 0;
strcpy(szCmd,"cmd.exe /a /s /c ");
strcat(szCmd,lpszCmd);
strCmdInfo.Format("KeyAss:>%s\r\n",lpszCmd);
m_strCmdInfo += strCmdInfo;

strCmdInfo.Empty();

sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0))
{
strCmdInfo = "\n创建通道失败...";
m_strCmdInfo += strCmdInfo;
goto END_EXEC;
}

STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL,szCmd,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
strCmdInfo.Format("执行程序 %s 失败\r\n",lpszCmd);
m_strCmdInfo += strCmdInfo;
goto END_EXEC;
}
CloseHandle(hWrite);

while (1)
{
if( dwRead > 10239 )
break;
Sleep(200);
if (ReadFile(hRead,&buffer[dwRead],10239-dwRead,&bytesRead,NULL) == NULL)
break;
dwRead += bytesRead;
bytesRead = 0 ;
strCmdInfo += buffer;
m_strCmdInfo += strCmdInfo;
m_ctrlCmdInfo.SetWindowText(m_strCmdInfo);
nLen = m_strCmdInfo.GetLength();
m_ctrlCmdInfo.SetSel(nLen,nLen);
}
CloseHandle(hRead);

END_EXEC:
m_ctrlCmdInfo.SetWindowText(m_strCmdInfo);
nLen = m_strCmdInfo.GetLength();
m_ctrlCmdInfo.SetSel(nLen,nLen);

m_strCmd.Empty();
SetDlgItemText(IDC_COMMAND,m_strCmd);
}
ringphone 2006-11-13
  • 打赏
  • 举报
回复
StartupInfo.hStdOutput = hOutputFile;
要使其生效必须指定StartupInfo.dwFlags = STARTF_USESTDHANDLES;
Y___Y 2006-11-13
  • 打赏
  • 举报
回复
VC++下命名管道编程的原理及实现
http://blog.csdn.net/Y___Y/archive/2006/11/07/1371254.aspx
incats 2006-11-13
  • 打赏
  • 举报
回复
说笨方法的那位,谢谢你! 但不是我想要的。

我需要的是重定向,不是从CONSOLE再读取。

那位说命名管道的,请提供链接,谢谢!

再有, CREATEPROCESS里那个STARTUPINFO的成员变量,按说明来看,应该能够实现这一需求的,不知为何不行?
mynamelj 2006-11-13
  • 打赏
  • 举报
回复
void main()
{
printf("message");

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

COORD dwPos = {0, 0};
TCHAR szOut[255];
DWORD cReadNumber;
ReadConsoleOutputCharacter(hOut, szOut, 255, dwPos &cReadNumber);

printf("This string of read:%s\n", (char*)szOut);
}
这是第三版,增加了大量关于键盘缓冲区操作和输入、输出操作的知识讲解,并修改了多处前两版中文字、语句错误的地方。 前两个版本由于我等级不够无法删除,此处留下前两版的地址,希望对大家有用。 第一版:http://download.csdn.net/source/3056070 第二版:http://download.csdn.net/source/3332359 以下为第三版本的目录: C/C++控制台界面编程(V 3) 1 目录 - 1 - 第一部分 控制台界面编程预备知识 1 1) Visual Studio 2005中控制台程序的类型 1 2) 转义字符及格式化输入、输出 1 a) 制表符\t 2 b) 回退字符\b 4 c) ASCII码表 6 d) 以%开头的格式控制符 9 e) 数据流的格式设置 10 3) C和C++库的输入、输出操作 12 a) stdio.h中的常用输入、输出函数 13 b) basic_stream中的输入、输出操作 13 4) 键盘缓冲区处理 15 5) 关于C/C++中的字符串拼接问题 17 6) 怎样从控制台复制粘贴文字 18 7) 将批处理bat转换为exe程序 18 8) 在Visual Studio 2005中设置控制台程序的图标 18 9) 重定向控制台程序的输出 19 第二部分 控制台界面编程详解 20 1) 概述 20 2) 控制台文本窗口编程的一般控制步骤 21 3) 控制台窗口操作函数 21 4) 文本属性操作 25 5) 文本输出 28 6) 文本操作示例 28 7) 滚动和移动 34 8) 光标操作 36 9) 读取键盘信息 37 10) 读取鼠标信息 44 11) 结束语 46 第三部分 附录 1 1) 分数等级划分工具 1 a) controlio.h文件 1 b) Main.c文件 5 2) 简易俄罗斯方块 6 a) 代码Main.c文件 7 3) 模拟实现可用鼠标、键盘控制的菜单和窗口 11 这是第三版,增加了大量关于键盘缓冲区操作和输入、输出操作的知识讲解,并修改了多处前两版中文字、语句错误的地方。 前两个版本由于我等级不够无法删除,此处留下前两版的地址,希望对大家有用。 第一版:http://download.csdn.net/source/3056070 第二版:http://download.csdn.net/source/3332359

16,547

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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