CMD ausführen und auslesen



  • Hallo,

    ich hab da ein kleines Problem. Ich möchte mir eine "Oberfläche" für den CMD programmieren. Ich hab da ein Memofeld und ein Editfeld. Das Memofeld soll das Ausgabe-, das Editfeld das Eingabefeld sein. Ich weiß, dass man über system("Befehl") Befehle im CMD ausführen lassen kann. Nur weiß ich nicht wie ich das Resultat des Befehls in das Memofeld angezeigt bekomme. Z.B. gibt man "dir" ein und er soll im aktuellen Ordner die Ordner anzeigen. Und beim Start des Programmes soll halt das gleiche kommen wie beim Start des CMDs:

    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.

    C:\Dokumente und Einstellungen\Administrator>

    Kann mir da einer helfen?

    Gruß
    ElBartoME



  • Kannst ja an deine Eingabe ein "> Dateiname" anhängen, und diese Datei dann in dein Memo laden.



  • Dann hab ich viele Txt dateien. Ich hab noch was gefunden:

    CMD /A Ausgabe interner Befehle in eine Pipe oder Datei im ANSI-Format.

    Weiß jemand wie ich das direkt in C++ ausgeben kann



  • Dann hab ich viele Txt dateien.

    Nö, nur eine ... 😉



  • Stimmt..und das für ich dann am besten mit ShellExecute aus oder?



  • oder du machst das ganze mit CreatePipe. Das hat ein folgende Vorteile:
    - du benötigst keine Datei
    - du kannst noch während das DOS Programm läuft die ersten Ergebnisse in Empfang nehmen



  • Hallo, danke für den Tipp, aber wie mache in denn eine Pipe?



  • hier ein ganz kleines Beispiel ohne Fehlerbehandlung und auch nicht besonders sauber
    programmiert. Hab gerade leider nicht mehr Zeit. Du siehst aber wie es im Prinzip
    funktioniert.

    AnsiString GetDOSPipe(AnsiString strDOSCommand)
    {
        // strDOSCommand: z.B.: cmd /c dir
    
        PROCESS_INFORMATION pi;
        STARTUPINFO si;
        SECURITY_ATTRIBUTES sa;
        HANDLE hReadPipe, hWritePipe;
        char Buffer[4000];
        DWORD dwRead;
    
        sa.nLength = sizeof (SECURITY_ATTRIBUTES);
        sa.lpSecurityDescriptor = NULL;
        sa.bInheritHandle = true;
    
        CreatePipe(&hReadPipe, &hWritePipe, &sa, 2500000);
    
        memset(&si, 0, sizeof(STARTUPINFO));
        si.cb = sizeof (STARTUPINFO);
        si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;
        si.hStdOutput = hWritePipe;
    
        CreateProcess(NULL, strDOSCommand.c_str(), NULL, NULL, true, NULL, NULL, "C:\\", &si, &pi);
    
        CloseHandle(pi.hThread);
        WaitForSingleObject(pi.hProcess, 30000);
    
        memset(Buffer, 0, 4000);
        ReadFile(hReadPipe,&Buffer,sizeof(Buffer), &dwRead, NULL);
        int i=0;
        AnsiString strOut="";
        while (Buffer[i]) {
            strOut=strOut+Buffer[i++];
        }
        return strOut;
    }
    


  • Dankeschön ^^
    Es geht!



  • Hi Leutz,
    bin Kumpel von ElBartoMe und schreib auch an dem Programm mit. Läuft eigentlich alles schon ganz gut, bzw. wir wissen wie wirs machen (is ja die Hauptsache :D). Nur eine Sache bereitet uns noch probleme undzwar ist das der Schreibschutz. Jedes Memo-Feld verfügt ja über eine ReadOnly Eigentschaft, die das gesamte Memo betrifft. Gibt es eine leichte Möglichkeit die Ausgabe der Pipe ReadOnly zu setzten?

    Unsere Überlegung:
    Wir legen uns einen Integer zeichen=0 an. Bei jeder Zeicheneingabe zählen wir zeichen um 1 hoch (mittels OnKeyPress) und sagen dann wenn die Rücktaste gedrückt wird, man darf nur solange drücken bis Zeichen wieder = 0. Problem bleibt dann halt noch das löschen über Markieren.

    mfg cb



  • Das stimmt. Allerdings habe ich noch ein Problem. Es werden keien ä, ö und ü mit übertragen. Es kommen dafür andere Zeichen. Wie kann ich das richtig machen?

    Gruß
    ElBartoME



  • Also das mit den Umlauten habe ich schon hinbekommen. Nur hab ich noch eine Frage.
    1. Wie kann man der Pipe klar machen, dass wenn man einen falschen Befehl eingibt, der die Fehlermeldung zurückgeben soll (Z.B. gebe ich "asd" ein. Diesen Befehl gibt es ja nicht. Anstatt einen Fehler zurückzugeben, stürzt das Programm ab).
    Muss man wirklich eine riesen Switch mit allen Befehlen machen? (Verzeichnisse müssen auch ausgelesen werden und es muss auf Vorhandenheit geprüft werden)

    Im Prinzip würde mir es schon reichen, wenn mir jemand einfach mal den Aufbau einer Pipe erklären würde. Der Code von "Acidmrp" funktioniert zwar, nur blicke ich in dem Code nicht wirklich durch. Es sind viele Deklarationen drinnen von denen ich in meinem Leben noch nichts gehört hab.

    Danke im Voraus.

    Gruß
    ElBartoME



  • weiß keiner weiter?



  • Hallo, Ich habe ganz genau das gleiche Problem, doch leider funktioniert die von Acidrmp veröffentlichte Funktion bei mir nicht. Muß man dort noch etwas ändern, damit es geht oder habt ihr das genau so übernommen ?

    Bye - Peter



  • Entschuldigung ! Ich nehme alles zurück. Ich hatte nur nichts gesehen, weil der Process mit SW_HIDE generiert worden war und meine aufgerufenen Konsolenapplikation erst beendete, wenn man irgend eine Taste drückt. Das ging natürlich nie. Jetzt funktioniert es !



  • Soweit bin ich ja zufrieden, aber jetzt habe ich noch ein Problem:
    Ich rufe per Knopfdruck ein Konsolenprogramm auf und will die ganzen Ausgabe aus der Pipe in einem Memo ausgeben. Solange das Konsolenprogramm läuft funktioniert das Ganze auch. Wenn das Konsolenprogramm beendet wird hängt mein Programm.
    Das liegt natürlich daran, daß ReadFile erst wieder zurück kommt, wenn aus der Pipe etwas gelesen wurde. Wenn das Konsolenprogramm aber beendet wurde, kommt ReadFile nie mehr zurück. Deshalb frage ich vorher mit MsgWaitForMultipleObjects ab ob irgend ein Event vorliegt und setzte ein Timeout von 1 Sekunde. Nur wenn es sich dann nicht um einen Timeout handelt rufe ich ReadFile auf. Die letzte Ausgabe des Konsolenprogramms führt auch wieder zum ReadFile, doch dann ist das Konsolenprogramm leider schon beendet und ich habe wieder meinen Deadlock. Nur wenn ich das Ende des Prozesses mit GetProcessTimes abfrage und es wurde nichts mehr vom Konsolenprogramm ausgegeben, kann mein Programm ohne Deadlock beendet werden.

    Mach ich hier irgend etwas zu kompliziert oder hat jemand eine Idee wie ich das Problem lösen kann?

    Bye - Peter


Anmelden zum Antworten