Komandozeilentool starten? (C++ Ersatz für System())



  • Hallo Forum,

    ich möchte von einer C++ Anwendung aus ein Kommandozeilentool starten. Unter C wäre das "system("Mytool.exe -version");"
    Der Versionsstring würde auf der Kommandozeile des aufrufenden C Programms erscheinen. So soll es auch im C++ Programm sein.

    Was benutzt man da unter C++?
    ShellExecute(0, "open", "MyTool.exe -version", "", "", 0);
    //system("MyTool.exe -version");
    Der Versionsstring erscheint nicht auf der Kommandozeile. CreateProcess aus der FAQ hier hat auch nicht funktioniert.

    Vielen Dank

    Peter



  • Was heisst "CreateProcess hat nicht funktioniert"?



  • Der Versionstext soll auf der Kommandozeile erscheinen. Das tut er nicht.

    Nehmen wir als Beispiel Java:

    //Die geht (Datei vorhanden):
    system("java.exe -version > d:\\ver.txt");
    
    // Das nicht (Keine Datei unter D):
    PROCESS_INFORMATION pi = {0};
    STARTUPINFO si = {sizeof(si)};
    si.wShowWindow = SW_NORMAL;
    CreateProcess("java.exe -version > d:\\ver.txt", "", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    

    Ich vermutet das nicht die Path Variable verwendet wurde. Die Applikation um die es geht ist in der Path Variablen drin.

    EDIT: Link zu ShellExecute();
    http://www.cbuilder.de/artikel/progstarten/ShellExecute.html



  • Der *erste* Parameter muss NULL sein und der zweite ein LPTSTR auf die Commandozeile mit Parameter (aber *kein* String-Literal!)

    Siehe Beispiel in der MSDN:
    http://msdn2.microsoft.com/en-us/library/ms682425.aspx
    http://msdn2.microsoft.com/en-us/library/ms682512.aspx



  • Hallo Jochen,

    der String Literal wäre falsch weil die Unicode Version von CreateProcess diesen String beschreiben will.

    Aber wie kann ich CreateProcess sagen das er die Path Variable benutzen soll?
    Diese funktioniert ja:
    CreateProcess(0, "C:\\Program Files\\Java\\jre1.5.0_10\\bin\\java.exe -version", 0, 0, FALSE, 0, 0, 0, &si, &pi);
    CreateProcess("C:\\Program Files\\Java\\jre1.5.0_10\\bin\\java.exe -version", 0, 0, 0, FALSE, 0, 0, 0, &si, &pi);

    Ich möchte den absoluten Pfad aber nicht angeben oder herausfinden.

    Peter


  • Mod

    Gar nicht! Das machen nur die "höherwertigen" Funktionen! Wie z.B. ShellExecute(Ex)

    Die Doku zu Createprocess sagt klar:
    The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a partial name, the function uses the current drive and current directory to complete the specification. The function will not use the search path. If the file name does not contain an extension, .exe is assumed. Therefore, if the file name extension is .com, this parameter must include the .com extension.

    Also warum nicht ShellExecute(Ex) verwenden?

    BTW: Ich habe noch nie verstanden warum sich alle auf CreateProcess stürzen und die viel einfacheren Funktionen außen vor lassen.



  • Es wird doch die PATH Variable benutzt?

    If the file name does not contain a directory path, the system searches for the executable file in the following sequence:
    ...
    6. The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.

    Quelle: http://msdn2.microsoft.com/en-us/library/ms682425.aspx

    HINSTANCE hInst;
    // Dies geht auch nur wenn ich den vollen Pfad zu Java angebe:
    hInst = ShellExecute( 0, "open", "java.exe -version", "", "", SW_SHOW);
    // Java ist korrekt in $PATH eingetragen. Auf der Kommandozeile (cmd) kann ich java -version benutzen.
    

    Ich habe das Problem über eine extern "C" Funktion und den system Aufruf gelösst.


  • Mod

    peterfarge_X schrieb:

    Es wird doch die PATH Variable benutzt?

    If the file name does not contain a directory path, the system searches for the executable file in the following sequence:
    ...
    6. The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.

    Quelle: http://msdn2.microsoft.com/en-us/library/ms682425.aspx

    Upps. Sorry! Ja Du hast recht. Ich habe die Infos zum falschen Parameter gelesen und gepostet...

    D.h. wie haben beide Recht: 🙂
    Wird der erste Parameter übergeben, gilt nur der und PATH wird nicht benutzt.
    Wird der zweite Parameter übergeben und der erste ist NULL dann wird PATH benutzt!



  • Ist alles geklärt?
    Wegen der schönen Sammlung aller Varianten und Links dazu würde ich das gern in die FAQ schieben. 🙂



  • Meine funktionierende Lösung:

    #include <stdio.h>
    extern "C" void PrintJavaVersion(void) {
    	system("java.exe -version");
    }
    

    Hier wird eine extra Konsole geöffnet und nicht in die bestehende Konsole geschrieben:

    #include <shellapi.h>
    ShellExecute( 0, "open", "java.exe", "", "", SW_SHOW);
    

    Hier passiert gar nichts. Jedenfalls gibt es keine aaaa.txt:

    #include <shellapi.h>
    ShellExecute( 0, "open", "java.exe -version > d:\\aaaa.txt", "", "", SW_SHOW);
    

    Bei CreateProcess() war es ähnlich wie bei ShellExecute().

    Da ich an einem Prototypen sitze reicht mir die Lösung. Später wird eine richtige GUI rangehängt, da fällt die Konsole eh weg.


  • Mod

    CreateProcess wird be system auf eine ganz spezielle Weise verwendet.
    system, spwanl und Konsorten laden nach lpReserved2 einen Array der aktuellen Handles (d.h. auch der Konsole) und vererbt die an den neuen Prozess.

    Wenn Du also keine neue Konsole aus einer bestehenden Konsole erzeugen willst musst Du das entsprechende Ausgabehandle vererben.

    Schau mal in den Code von _wdospawn in der Datei!
    C:\Programme\Microsoft Visual Studio 8\VC\crt\src\dospawn.c



  • HI,

    ich hänge meine Frage einfach mal hier an, damit ich kein neues Thema aufmachen muss.

    Es ist folgendes:
    Ich habe ein Konsolenprogramm das ich über CreateProcess() starte. Ich hab nur die exe und kann an dem Konsolenprog nichts mehr ändern!
    Das Programm zu starten klappt bestens. Allerdings ist es nun so, dass sich das Fenster sofort wieder schließt, wenn das Konsolenprog seine Aufgabe erledigt hat. Ich möchte aber nun, dass es offen bleit.

    Welche Parameter muss ich wo angeben, damit sich das Fenster nicht von selbst schließt?
    In der Doku hab ich leider nichts gefunden.

    Mfg


  • Mod

    Solch einen Schalter gibt es niht. Du müsstest hier eine CMD.EXE starten, die Dein Programm dann ausführt. Allerdings bleint dann die Einmgabeaufforderung offen.

    Wenn Du das Programm so manipulierst, dass es auf eine Eingabe wartet, dann geht das natürlich auch.


Log in to reply