ShellExecute & Co. zum XXX. Mal



  • Also, bei mir siehts so aus: (bei mir gings allerding nur darum die Konsolenausgabe von gunzip "einzufangen" nicht mit dem Programm zu interagieren...)

    //-- Irgendwo in der Funktion...
    
    /* Puffer initialisieren der so gross ist wie der Puffer der Pipe */
    char *Buffer_charp = new char[PIPE_SIZE];
    {
        memset(Buffer_charp, 0, PIPE_SIZE);
    
        DWORD BytesRead_DWORD = 0;
        DWORD BytesToRead_DWORD = 0;
    
        /* Solange ausführen, bis das Child-Programm zu Ende ist: */
        do
        {
            /* Wenns was zu lesen gibt ... */
            if (BytesToRead_DWORD)
            {
                /* ... werden die anstehenden Bytes gelesen. */
                ReadFile(readHandle_HANDLE,
                         Buffer_charp,
                         BytesToRead_DWORD,
                         &BytesRead_DWORD,
                         NULL);
    
                /* Was auch immer mit dem gelesenen Wert zu tun ist, kann man 
                   hier erledigen... */
    
                ProcessMessages(); /* globale funktion, siehe weiter unten. */
            }
    
            /* Die Anzahl der anstehenden Bytes ermitteln. Da wir nur die Anzahl 
               bytes wissen wollen, brauchen wir nichts zu Lesen und entsprechend
               auch keine Puffer zu übergeben. */
            PeekNamedPipe(readHandle_HANDLE, 
                          NULL, /* Kein Puffer nötig, denn */
                          0,    /* wir lesen 0 Bytes, wodurch */
                          NULL, /* auch kein BytesRead nötig ist aber */
                          &BytesToRead_DWORD, /* Die anzahl verfügbarer bytes schon */
                          NULL);
        }
        while (BytesToread_DWORD > 0);
    }
    delete [] Buffer_charp;
    
    //-- Irgendwie gehts dann hier in der Funktion wohl weiter...
    
    //-- Eine neue Funktion...
    /* Leert die komplette MessageQueue und verarbeitet die Messages.
       Sonst erweckt die Applikation den Eindruck "abgestürzt" zu sein, da
       weder Interaktion möglich ist, noch ein Refresh/repaint stattfindet 
       (Achtung, nur mit MFC) 
       Das Listing hab ich irgendwo aus de Knowledgebase... */
    void ProcessMessages(void)
    {
        MSG message_MSG;
    
        // überprüft ob die Queue noch eine Nachricht enthält.
        while (::PeekMessage(&message_MSG, NULL, 0, 0, PM_NOREMOVE))
        {
            if (!AfxGetThread()->PumpMessage())
                return;
        }
    }
    

    Das Obige Beispiel liest einfach unersättlich alles ein, was das Child so den ganzen Tag von sich gibt. Gibts nichts zu lesen, springts raus.

    Vielleicht wird dir mein Gefasel jetzt etwas klarer. Das hat bei mir in der MFC-Anwendung eigentlich bestens funktioniert...

    -junix

    [ Dieser Beitrag wurde am 01.07.2003 um 15:16 Uhr von junix editiert. ]



  • ja danke! es wird mir schon etwas klarer. ich muss halt sehen wie ich das so hinbekomme, dass ich eine art dialog führen kann mit meiner konsole.

    ich bin zudem noch unsicher welche variablen ich nachher killen muss. klar die handles schließe ich alle mit closehandle(); und den pointer den du erstellst muss man mit delete putzen. aber erledigt sich der rest von selbst?
    und den inhalt der pipes sollte man doch nach einem "wortwechsel" (a sagt b hört) leeren. machst du das mit peekmessage() ?

    gut gut, ich werde dann nochmal etwas basteln.

    danke für die geduld!



  • ReadFile() entfernt die Anzahl bytes die du gelesen hast aus der Pipe.. Ausser den von dir mit new erstellten Variablen und den Handles musst du nichts freigeben.

    -junix



  • Hi junix,

    mir ist soweit klar was in deinem Code passiert. Bis auf PumpMessage.

    Ich gehe eigentlich genauso vor wie du, nur, dass ich nich in einer Schleife lese.

    Mein Problem ist, dass mir PeekNamedPipe immer 0 zurückgibt. Warum?
    Nachdem ich CreateProcess ausgeführt hab, läuft mein Programm und wartet auf ne eingabe.
    Wenn ich dann beenden will schreibe ich mit WriteFile den Befehl "exit\r\n" in StdIn. (Im Win32-Prog kommt das auch an)
    Danach lese ich im Win32-Prog den StdOut und bekomm "exit" und die Antwort darauf angezeigt.

    Soweit kommt es im MFC-Prog erst garnich. Wenn ich mit WriteFile "exit" schreibe passiert überhauptnix.

    Das klingt sicher alles sehr verwirrend! Ich bin halt der meinung, dass ich das mache was du tust und es trotzdem nich funktioniert.

    Vielleicht weißt du ja noch was?

    Ich such mal weiter...



  • Huhu,

    wenn ich mir das MFC-Prog beim debuggen so angucke, laufen ein paar Dinge anders als im Win32-Prog.

    Als erstes bekommen meine Handles zu STDIN und STDOUT schonmal den gleichen Wert:

    hStdIn = 0x00000000
    hStdOut = 0x00000000

    und wenn ReadFile aufgerufen wird, setzt er den Parameter dwRead nicht.

    ReadFile(hOutReadDpl, chBuf, dwAvailable, &dwRead, NULL);

    das gleiche bei WriteFile. Der Parameter dwWritten wird auch nicht gesetzt.

    WriteFile(hInWriteDpl, chBuf, dwRead, &dwWritten, NULL);

    In der Win32-Anwendung funktioniert das. Ich bin echt am verzweifeln.
    Das mit dem STDIN un STDOUT kann ich mir ja noch erklären, weil es ja ne MFC-Anwendung ist... aber das andere.



  • Hi ...

    Habs jetzt mit Hilfe von nem Ex-Dozenten rausbekommen. Der meinte es läge an der fehlenden Konsole im MFC-Prog.
    Jetzt lege ich mir in der InitInstance ne Konsole an und verstecke sie.

    BOOL	res = AllocConsole();
    	if (res) {
    		HWND	hwnd = GetConsoleWindow();
    		ShowWindow(hwnd, SW_HIDE);
    	}
    

    Der Rest funktioniert dann eigentlich auch wie beim Win32-Prog.

    Hab gedacht es wäre vielleicht interessant. Aus dem WinAPI-Thread hat sich zwar am Ende ein MFC_Thread entwickelt aber nimmt mir hoffentlich keiner krumm.

    Gruß Tody


Anmelden zum Antworten