一个关于在窗口程序中打开控制台程序并与其进行通讯的问题

ksndyjs 2005-05-18 11:04:46
我在窗口程序中用CreateProcess打开了一个控制台程序,用SW_HIDE隐藏控制台。并且用匿名管道与其通讯。
也就是说,控制台对用户是不可见的。完全依靠我自己的程序与控制台交互。用户是不能输入的。
那现在就有一个问题。
就是这个控制台程序可能进行到一定的时候需要用户进行输入。否则就死在那里。而我刚才说了,由于对用户不可见,所以用户无法输入。完全需要靠我自己的程序对控制台进行输入,而且输入的内容又不是命令行参数,那请问该怎么写程序输入呢。当然输入的内容是用户设置好的。

谢谢!
...全文
228 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
idAnts 2005-05-18
  • 打赏
  • 举报
回复
你创建进程的时候重定向啊。
ksndyjs 2005-05-18
  • 打赏
  • 举报
回复
不能。因为进程已经在执行中了
idAnts 2005-05-18
  • 打赏
  • 举报
回复
你能定向它的输出,不能定向它的输入么?
ksndyjs 2005-05-18
  • 打赏
  • 举报
回复
传回去?怎么传回去呢请问。
我原来的匿名管道是控制台的输出到我应用程序的输入。
难道可以共用吗?
idAnts 2005-05-18
  • 打赏
  • 举报
回复
你的窗口程序提供借口写,等写完用管道传回去。
idAnts 2005-05-18
  • 打赏
  • 举报
回复
不是死机,是在等待管道数据,因为第一次把数据读出来了,再读的时候没数据了,就等着有数据才能读进去,这也是为什么要用线程来处理的原因。
柯本 2005-05-18
  • 打赏
  • 举报
回复
要用多线程做,看我的程序:
http://community.csdn.net/Expert/topic/3474/3474250.xml?temp=.8702204
ksndyjs 2005-05-18
  • 打赏
  • 举报
回复
哦。谢谢了!

可是我刚才调试的时候碰到了一个问题。很奇怪。就是ReadFile的时候,如果是单步执行,则能完全读取控制台的输出。如果是直接运行程序就只能读到第一个\r\n。

另外ReadFile如果第一次就全部读取完的话,再ReadFile一次会死机。

请问这是怎么回事啊
idAnts 2005-05-18
  • 打赏
  • 举报
回复
对,就是设置那个si.hStdInput。
你可以创建2个管道。创建一个线程,在线程里创建新的进程,然后开始监视程序的输出,而你的主程序获得创建的管道后,有需要就对管道进行写操作。我写过一个cmd的例子,你可以看下:

char cmdbuffer[1024];
HANDLE hReadPipe;
HANDLE hReadPipe2;
HANDLE hWritePipe;
HANDLE hWritePipe2;

DWORD __stdcall ThreadFun(void *pVoid)
{
HWND hwnd = *((HWND *)pVoid);//参数是主线程窗口句柄

SECURITY_ATTRIBUTES sat;
STARTUPINFO startupinfo;
PROCESS_INFORMATION pinfo;
BYTE buffer[1024];
DWORD byteRead;
CString rString;


sat.nLength=sizeof(SECURITY_ATTRIBUTES);
sat.bInheritHandle=true;
sat.lpSecurityDescriptor=NULL;
//第一个管道
if(!CreatePipe(&hReadPipe,&hWritePipe,&sat,NULL))
{
MessageBox(NULL,"Create Pipe Error!","error!",MB_OK);
return 0;
}
//第二个管道
if(!CreatePipe(&hReadPipe2,&hWritePipe2,&sat,NULL))
{
MessageBox(NULL,"Create Pipe2 Error!","error!",MB_OK);
return 0;
}
startupinfo.cb=sizeof(STARTUPINFO);
GetStartupInfo(&startupinfo);
startupinfo.hStdError=hWritePipe;
startupinfo.hStdOutput=hWritePipe;
startupinfo.hStdInput=hReadPipe2;//定向进程的标准输入
startupinfo.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
startupinfo.wShowWindow=SW_HIDE;
//创建cmd.exe
if(!CreateProcess(NULL,"c:\\winnt\\system32\\cmd.exe",NULL, NULL, TRUE, NULL, NULL, NULL,&startupinfo,&pinfo))
{
MessageBox(NULL,"create process error!","Error!",MB_OK);
return 0;
}
CloseHandle(hWritePipe);
CloseHandle(hReadPipe2);

//不停的读出cmd的输出,放到主窗口的信息框里
while(true)
{
RtlZeroMemory(buffer,1024);
if(ReadFile(hReadPipe,buffer,1023,&byteRead,NULL)==NULL)
break;
::SendMessage(GetDlgItem(hwnd,IDC_MSG),EM_SETSEL,-1,0);
::SendMessage(GetDlgItem(hwnd,IDC_MSG),EM_REPLACESEL,false,(long)buffer);
}
CloseHandle(hReadPipe);
CloseHandle(hWritePipe2);
return 0;
}

//主程序的发送按钮处理函数
void CCmdDlg::OnCmd()
{
DWORD byteRead;
//执行dir命令
strcpy(cmdbuffer,"dir\r\n");
WriteFile(hWritePipe2,cmdbuffer,strlen(cmdbuffer),&byteRead,NULL);
}
ksndyjs 2005-05-18
  • 打赏
  • 举报
回复
怎么定向呢?指定hStdInput字段?

把我的程序贴一下吧:

HANDLE hReadPipe,hWritePipe;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = true;

STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
if(Pipeused)
{
CreatePipe(&hReadPipe,&hWritePipe,&sa,0);
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
}

bool hProcess = CreateProcess(
NULL, // C-style字符串:应用程序的名称
exe_param,///c dir /?",
NULL, // 进程安全属性
NULL, // 线程安全属性
true, // 是否继承句柄的标志
NULL, // 创建标志
NULL, // C-Style字符串:环境设置
NULL, // C-Style字符串:执行目录
&si, // 启动信息
&pi
); // 进程信息

if(hProcess)
{
CloseHandle(pi.hThread);
if(Pipeused)
{
WaitForSingleObject(pi.hProcess,INFINITE);
GetExitCodeProcess(pi.hProcess,&dwExitCode);

}
CloseHandle(pi.hProcess);
}
else
return false;

DWORD bytesRead;
if(Pipeused)
{
if(ReadFile(hReadPipe,buf,4095,&bytesRead,NULL) != NULL)
{
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
}
}

请教就我这段程序该怎么做呢?si.hStdInput = .... 那样不行吧。

16,551

社区成员

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

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

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