SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
sa.nLength =sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if(!CreatePipe(&hRead,&hWrite,&sa,0))
{
MessageBox("Error OnCreatePipe()");
return;
}
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,"c:\windows\system32\cmd.exe /c dir/?"
,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
MessageBox("Error onCreateProcess()");
return;
}
CloseHandle(hWrite);
char buffer[4096] = {0};
DWORD bytesRead;
while (true)
{
if(ReadFile(hRead,buffer,4095,&bytesRead,NULL) ==NULL)
break;
CString strTmp;
strTmp = buffer;
MessageBox(strTmp);
//UpdateData(false);
Sleep(200);
}
--------------------------------------------------------------------
Creating a Child Process with Redirected Input and Output
The example in this topic demonstrates how to create a childprocess using the CreateProcess function from a console process. Italso demonstrates a technique for using anonymous pipes to redirectthe child process's standard input and output handles. Note thatnamed pipes can also be used to redirect process I/O.
The CreatePipe function uses the SECURITY_ATTRIBUTES structureto create inheritable handles to the read and write ends of twopipes. The read end of one pipe serves as standard input for thechild process, and the write end of the other pipe is the standardoutput for the child process. These pipe handles are specified inthe STARTUPINFO structure, which makes them the standard handlesinherited by the child process.
The parent process uses the other ends of the pipes to write tothe child process's input and read the child process's output. Thehandles to these ends of the pipe are also inheritable. However,the handle must not be inherited. Before creating the childprocess, the parent process uses SetHandleInformation to ensurethat the read handle for standard input and the write handle forstandard output cannot be inherited. For more information, seePipes.
The following is the code for the parent process. It takes a singlecommand-line argument: the name of a text file.
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define BUFSIZE 4096
HANDLE hChildStdinRd, hChildStdinWr,
hChildStdoutRd,hChildStdoutWr,
hInputFile, hStdout;
BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPSTR);
int _tmain(int argc, TCHAR *argv[])
{
SECURITY_ATTRIBUTESsaAttr;
BOOL fSuccess;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength =sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle =TRUE;
saAttr.lpSecurityDescriptor =NULL;
// Get the handle to the current STDOUT.
hStdout =GetStdHandle(STD_OUTPUT_HANDLE);
// Create a pipe for the child process's STDOUT.
if (!CreatePipe(&hChildStdoutRd,&hChildStdoutWr, &saAttr, 0))
ErrorExit("Stdout pipe creation failedn");
// Ensure the read handle to the pipe for STDOUT is notinherited.
SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);
// Create a pipe for the child process's STDIN.
if (!CreatePipe(&hChildStdinRd,&hChildStdinWr, &saAttr, 0))
ErrorExit("Stdin pipe creation failedn");
// Ensure the write handle to the pipe for STDIN is notinherited.
SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0);
// Now create the child process.
fSuccess =CreateChildProcess();
if (! fSuccess)
ErrorExit("Create process failed with");
// Get a handle to the parent's input file.
if (argc == 1)
ErrorExit("Please specify an input file");
printf( "nContents of%s:nn", argv[1]);
hInputFile =CreateFile(argv[1], GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if (hInputFile ==INVALID_HANDLE_VALUE)
ErrorExit("CreateFile failed");
// Write to pipe that is the standard input for a childprocess.
WriteToPipe();
// Read from pipe that is the standard output for childprocess.
ReadFromPipe();
return 0;
}
BOOL CreateChildProcess()
{
TCHARszCmdline[]=TEXT("child");
PROCESS_INFORMATIONpiProcInfo;
STARTUPINFO siStartInfo;
BOOL bFuncRetn = FALSE;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb =sizeof(STARTUPINFO);
siStartInfo.hStdError =hChildStdoutWr;
siStartInfo.hStdOutput =hChildStdoutWr;
siStartInfo.hStdInput =hChildStdinRd;
siStartInfo.dwFlags |=STARTF_USESTDHANDLES;
// Create the child process.
bFuncRetn =CreateProcess(NULL,
szCmdline,// command line
NULL,// process security attributes
NULL,// primary thread security attributes
TRUE,// handles are inherited
0,// creation flags
NULL,// use parent's environment
NULL,// use parent's current directory
&siStartInfo, // STARTUPINFOpointer
&piProcInfo); // receivesPROCESS_INFORMATION
if (bFuncRetn == 0)
ErrorExit("CreateProcess failedn");
else
{
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
return bFuncRetn;
}
}
VOID WriteToPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
// Read from a file and write its contents to a pipe.
for (;;)
{
if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead,NULL) ||
dwRead == 0) break;
if (! WriteFile(hChildStdinWr, chBuf, dwRead,
&dwWritten, NULL)) break;
}
// Close the pipe handle so the child process stops reading.
if (!CloseHandle(hChildStdinWr))
ErrorExit("Close pipe failedn");
}
VOID ReadFromPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
// Close the write end of the pipe before reading from the
// read end of the pipe.
if(!CloseHandle(hChildStdoutWr))
ErrorExit("Closing handle failed");
// Read output from the child process, and write to parent'sSTDOUT.
for (;;)
{
if( !ReadFile( hChildStdoutRd, chBuf, BUFSIZE,&dwRead,
NULL) || dwRead == 0) break;
if (! WriteFile(hStdout, chBuf, dwRead, &dwWritten,NULL))
break;
}
}
VOID ErrorExit (LPSTR lpszMessage)
{
fprintf(stderr, "%sn",lpszMessage);
ExitProcess(0);
}
The following is the code for the child process. It uses theinherited handles for STDIN and STDOUT to access the pipe createdby the parent. The parent process reads from its input file andwrites the information to a pipe. The child receives text throughthe pipe using STDIN and writes to the pipe using STDOUT. Theparent reads from the read end of the pipe and displays theinformation to its STDOUT.
#include <windows.h>
#define BUFSIZE 4096
VOID main(VOID)
{
CHAR chBuf[BUFSIZE];
DWORD dwRead, dwWritten;
HANDLE hStdin, hStdout;
BOOL fSuccess;
hStdout =GetStdHandle(STD_OUTPUT_HANDLE);
hStdin =GetStdHandle(STD_INPUT_HANDLE);
if ((hStdout ==INVALID_HANDLE_VALUE) ||
(hStdin == INVALID_HANDLE_VALUE))
ExitProcess(1);
for (;;)
{
// Read from standardinput.
fSuccess = ReadFile(hStdin, chBuf, BUFSIZE,&dwRead, NULL);
if (! fSuccess || dwRead == 0)
break;
// Write to standardoutput.
fSuccess = WriteFile(hStdout, chBuf, dwRead,&dwWritten, NULL);
if (! fSuccess)
break;
}
}