Click to See Complete Forum and Search --> : [RESOLVED] Writing to console problem


susiriss
September 26th, 2006, 06:19 AM
Hi all,
I am developing a program to communicate with a console mode application. So I spawned a child console process, created two pipes for Stdinput and Stdoutput of the console process, redirected their handles so that my process can communicate with it. First I tried to run cmd.exe on the console window, and test some commands in it. The command prompt appears on the console but my command does not display or executed. However, when I debug the app, I see the WriteFile succedes and the desired no. of bytes are written to the pipe. My code look like the following. Could you please help me & identify what I'm missing ....!


void CConsole::Create()
{
HANDLE hStdinWriteTmp,hStdoutReadTmp;// Temporary handles used by the parent
HANDLE hStdinRead,hStdoutWrite,hStdError;// Stdin, Stdout & Stderror handles
AllocConsole(); // Allocate my one and only console


SECURITY_ATTRIBUTES sa;

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

// Creating pipe for child's input
CreatePipe(&hStdinRead,&hStdinWriteTmp,&sa,0);
// Creating pipe for child's output
if(!CreatePipe(&hStdoutReadTmp,&hStdoutWrite,&sa,0))
AfxMessageBox("pipe failed",MB_ICONERROR,0);

//Duplicate the Write handle so that it is not inheritable
::DuplicateHandle(::GetCurrentProcess(),hStdinWriteTmp,
::GetCurrentProcess(),&m_hStdinWrite, 0,
FALSE,DUPLICATE_SAME_ACCESS);

//Duplicate the Read handle so that it is not inheritable
::DuplicateHandle(::GetCurrentProcess(),hStdoutReadTmp,
::GetCurrentProcess(),&m_hStdoutRead, 0,
FALSE,DUPLICATE_SAME_ACCESS);

//Duplicate handle for the Std Error
::DuplicateHandle(::GetCurrentProcess(),hStdoutWrite,
::GetCurrentProcess(),&hStdError, 0,
TRUE,DUPLICATE_SAME_ACCESS);

//Close the duplicate handles inherited by the child
CloseHandle(hStdinWriteTmp);
CloseHandle(hStdoutReadTmp);
hStdinWriteTmp=INVALID_HANDLE_VALUE;
hStdoutReadTmp=INVALID_HANDLE_VALUE;

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.hStdOutput = hStdoutWrite;//GetStdHandle(STD_OUTPUT_HANDLE);//
si.hStdInput = hStdinRead;//GetStdHandle(STD_INPUT_HANDLE);
si.hStdError = hStdError;//GetStdHandle(STD_ERROR_HANDLE);
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESTDHANDLES;//| STARTF_USESHOWWINDOW;// ;
ZeroMemory( &pi, sizeof(pi) );

if(!::CreateProcess(NULL,"cmd.exe ",
NULL,NULL,FALSE,CREATE_NEW_PROCESS_GROUP,//CREATE_NEW_PROCESS_GROUP|
NULL,
NULL,&si,&pi))
AfxMessageBox("Process Error",MB_ICONERROR,0);
Execute("notepad\r\n");

CloseHandle(hStdinRead);
CloseHandle(hStdoutWrite);
CloseHandle(hStdError);

}
BOOL CConsole::Execute(LPCSTR szCmd)
{
DWORD nBytesWritten;
CString sCmd(szCmd);

if(!::WriteFile(m_hStdinWrite,(LPCTSTR)sCmd,sCmd.GetLength(),&nBytesWritten,NULL))
{
AfxMessageBox("Write to pipe failed",MB_ICONERROR,0);
return FALSE;
}
else
{
return TRUE;
}

}

susiriss
September 28th, 2006, 01:11 AM
The problem was resolved by myself !! :) :wave:

Mouse_103
April 8th, 2007, 11:15 AM
what was the problem?

susiriss
April 9th, 2007, 01:03 AM
well mouse_103,
For what purpose are you interesting on that? Are you facing a similar problem?
The one and only reasion for the console process coming and gone was due to the incorrect creation of it. You must create the process so that it can inherit handles of the parent process. Otherwise you the created process cannot access your pipe handles etc. For this, you have to set the 5th parameter of CreateProcess to be TRUE. That solves the problem....:thumb: