De uitvoer van stdout omleiden in cpp

Ik ben al een paar dagen op zoek naar een antwoord over dit probleem, ik hoop dat jullie me kunnen helpen. (Ik heb een aantal oplossingen gezocht en gevonden, maar elk heeft zijn eigen probleem ...).

Hier is het ding: Ik schrijf een automatisering op het werk, die verantwoordelijk is voor het starten van een extern ".exe" -bestand van een code geschreven door mijn collega's. Omdat die programma's die ze schrijven naar klanten gaan, mag ik hun code niet wijzigen. Die programma's, eenmaal gestart, wachten op specifieke toetsaanslagen en drukken een bericht af wanneer een legale toetsaanslag is ontvangen.

Mijn doel is dit: Om een ​​programma te schrijven dat het externe programma zal uitvoeren, verzend het de toetsaanslagen en ontvang de uitvoer van hun stdout. Tot nu toe heb ik het programma vanuit mijn programma kunnen uitvoeren (met behulp van ShellExecute) en een soort toetsenbordlistener (met behulp van SendMessage) gesimuleerd naar het andere programma. Ik kan zien dat het werkt - ik kan de uitvoer zien in de console van het geteste programma.

Ik probeer de berichten die in de shell van het geteste programma zijn afgedrukt in realtime op te halen (en krijg gewoon een grote hoeveelheid gegevens wanneer het programma wordt beëindigd), zodat ik het kan analyseren wanneer het zich voordoet.

Degenen die ik heb geprobeerd:

  • Een extern batchbestand schrijven met inline uitvoeromleiding naar een tekstbestand.
  • Freopen gebruiken.
  • Omleiding van de uitvoer tijdens het uitvoeren van "ShellExecute".
1
toegevoegd de auteur Bo Persson, de bron
U kunt uitvoer niet omleiden tijdens het gebruik van ShellExecute. Soortgelijke mechanisme in .net: msdn.microsoft.com/ en-us/library/& hellip;
toegevoegd de auteur Mohammad, de bron

1 antwoord

U gebruikt handvatten voor stdin, stdout en stderr. Maak een proces met CreateProcess-functie om die handvatten te krijgen. Voorbeeldcode - onvolledig voor uw zaak, maar een goed voorbeeld van hoe u dit moet doen:

#include 
#include 
#include 

    /*for test.exe
#include 
#include  */

void _tmain( int argc, TCHAR *argv[] )
{
    /*for test.exe
    std::cout << "test output" << std::endl;
    for (;;)
    {
        std::string line;
        std::getline(std::cin, line);
        std::cout << "line: " << line << std::endl;
    }
    return;*/
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

   //Start the child process. 
    if( !CreateProcess( NULL,  //No module name (use command line)
        "test.exe",       //Command line
        NULL,          //Process handle not inheritable
        NULL,          //Thread handle not inheritable
        FALSE,         //Set handle inheritance to FALSE
        0,             //No creation flags
        NULL,          //Use parent's environment block
        NULL,          //Use parent's starting directory 
        &si,           //Pointer to STARTUPINFO structure
        &pi )          //Pointer to PROCESS_INFORMATION structure
    ) 
    {
        printf( "CreateProcess failed (%d)\n", GetLastError() );
        return;
    }

   /*     HANDLE  hStdInput;
    HANDLE  hStdOutput;
    HANDLE  hStdError;*/
    HANDLE me_hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    HANDLE me_hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE proc_hStdInput = si.hStdInput;
    HANDLE proc_hStdOutput = si.hStdOutput;

                char buff[64];
                DWORD chars;
    while (!ReadConsole(me_hStdInput, buff, sizeof(buff), &chars, NULL))
    {
                    for (DWORD written = 0, writtenThisTime; written < chars; written += writtenThisTime)                   
                        if (!WriteConsole(proc_hStdOutput, buff + written, chars - written, &writtenThisTime, NULL))
                        {
                            //handle error - TODO
                        }
                }
                //possibly handle error for ReadConsole - TODO  


   //Wait until child process exits.
    //WaitForSingleObject( pi.hProcess, INFINITE );

   //Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
}
0
toegevoegd
Wees voorzichtig met het doorgeven van een letterlijke of constante aan CreateProces (). Het is een gebruikelijke gotta en resulteert in ongedefinieerd gedrag omdat CreateProcess() tijdelijk naar deze locatie zal schrijven. Zie het antwoord hier: stackoverflow.com/questions/9427008/…
toegevoegd de auteur namezero, de bron
STARTUPINFO is een invoerparameter die wordt gebruikt om opties voor het maken van processen te bieden, niet een uitvoerparameter die informatie over het gemaakte proces ontvangt. STARTUPINFO.hStdInput, etc. zal allemaal NULL zijn na het aanroepen van CreateProcess in het bovenstaande voorbeeld - het zal niet werken.
toegevoegd de auteur Dan McDougall, de bron