Главная страница | назад





Article #15201: How to redirect STDOUT/STDIN

 Question and Answer Database

FAQ201C.txt   How to redirect STDOUT/STDIN
Category   :Windows API
Platform    :All
Product    :C++Builder  1.x

Question:
I want to redirect the stdio/stdout of a console app that 
I spawn in my Builder app.

Answer:
Here is a snippet of code that illistrates how to do this.



void RunConsoleApp (void){
    STARTUPINFO sui;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    HANDLE hReadPipe, hWritePipe;
    char Buffer[4000];
    DWORD dwRead;


    //setup the stdout
    //fist create the sec attrib
    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = true;
    //create pipe handles
    CreatePipe(&hReadPipe, &hWritePipe, &sa, 2500000);
    if (hReadPipe == INVALID_HANDLE_VALUE ||
        hWritePipe == INVALID_HANDLE_VALUE){
      	MessageBox (Handle, "Not a valid Handle for STDOUT", NULL,
           			MB_OK | MB_ICONEXCLAMATION);
        return;
    }

    //setup the start up info
    memset(&sui, 0, sizeof(STARTUPINFO));
    sui.cb = sizeof (STARTUPINFO);
    sui.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    sui.wShowWindow = SW_HIDE;
    sui.hStdOutput = hWritePipe;

    if (!CreateProcess ("console.exe", // pointer to name of executable module, getit fron the open dialog
    			NULL,	// pointer to command line string, have noe so NULL
			NULL,	// pointer to process security attributes, we don't need to inheriat the handle
			NULL,	// pointer to thread security attributes
			true,	// handle inheritance flag
			NULL,	// creation flags
			NULL,	// pointer to new environment block
			NULL,	// pointer to current directory name
			&sui,	// pointer to STARTUPINFO
			&pi 	// pointer to PROCESS_INFORMATION
			)){
		MessageBox ((HWND)Handle, "Could not create process", NULL,
          			MB_OK | MB_ICONEXCLAMATION);
        return;
    }
    CloseHandle(pi.hThread);
    WaitForSingleObject(pi.hProcess, 30000);

    //read from the pipe and put it in the richedit
    bool ReadLoopDone = false;
    Memo1->Lines->Clear();
    while (!ReadLoopDone){
    	memset(Buffer, 0, 4000);
        ReadFile(hReadPipe,
            	 &Buffer,
                 sizeof(Buffer),
            	 &dwRead,
            	 NULL);
        Memo1->Lines->Add(String(Buffer));
        if (dwRead < 4000) ReadLoopDone = true;
	}
    return;
}

7/2/98 10:32:32 AM
 

Last Modified: 01-SEP-99