CreateProcess Programm mit Datei öffnen



  • Hallo,

    Ziel ist es eine Word Datei mit Notepad zu öffnen (ist dann natürlich übertragbar auf alle anderen Programme).

    Habe dazu folgendes kleine Programm geschrieben:

    #include <iostream>
    using namespace std; 
    #include "windows.h"
    #include "TCHAR.h"
    
    int main(int _argc,char** _argv){
    
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
    si.wShowWindow = SW_SHOWNORMAL;
    
    PROCESS_INFORMATION pi;
    
    CreateProcess( L"C:\\WINDOWS\\Notepad.EXE", L"D:\\Readme.txt", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    
    	return 1;
    }
    

    Mit word dateien gings eh nicht, also hab ich es mit txt dateien versucht.
    Es wird aber immer nur das leere Notepad geöffnet.

    Wo liegt der Fehler?

    Danke



  • Der zweite Parameter gibt die an den Prozess zu übergebende CommandLine. Der erste Teil einer Command Line ist der auszuführende Command. Der erste Parameter ist also nicht das erste Ding in der Command Line, sondern das zweite... 😉

    Wobei ich es sowieso so machen würd:

    wchar_t cmdline[] = L"notepad D:\\Readme.txt";
    CreateProcessW(nullptr, cmdline, nullptr, nullptr, FALSE, 0U, nullptr, nullptr, &si, &pi);
    

    Beachte: Der zweite Parameter von CreateProcess ist ein non const String.



  • danke für deine antwort 🙂

    aber ich hab irgendwie absolut wchar_t probleme.
    ich treffe immer wieder auf diese dinger, aber ich checks einfach nicht.

    ich würde jetzt gern den pfad und aus einem file auslesen.
    aber erst mal zum verständnis würde es mir reichen wenn ich es mit wcin hinbekommen würde. naja und die strings dann natürlich zusammenfügen wäre auch ganz nett.

    wchar_t test[] = L"C:\\Program Files\\GIMP 2\\bin\\gimp-2.8.exe ";
    wchar_t test1[] = L"D:\\unbenannt.jpg"; 
    wcscat(test, test1);
    

    test wird bei "C:\\Program Files\\GIMP 2\\bin\\gimp-2.8.exe D:\\un" einfach abgeschnitten.

    und bei return von mail sagt er mir, das der stack um die variable test nicht passt.

    gimp wird geöffnet mit dem hinweis das "D:\\un" nicht geöffnet werden kann.

    Meine vielen Fragen sind jetzt: 😃

    1. Warum fügt der mir die zwei variablen nicht ordentlich zusammen?
    2. Wenn ich mit Ofstream die Datei einlese, dann hab ich ja normale strings, wie bekomme ich die dann in wchar_t konvertiert?
    3. ich finde keine literatur über wchar_t, lpstr, usw. würde das aber gerne kapieren. gibt es da vll irgendwo etwas mit beispielen damit man auch den output sieht? gibts da vll nen fachbegriff nach dem man suchen kann?



  • //nachtrag

    also die test virable passt, aber er kommt mit

    CreateProcessW(NULL, test, NULL, NULL, FALSE, 0U, NULL, NULL, &si, &pi);
    

    nicht klar. test ist beim debuggen zuerst richtig, und wird dann irgendwie abgeschnitten, ich weiß aber nicht warum 😞



  • lulu32 schrieb:

    wchar_t test[] = L"C:\\Program Files\\GIMP 2\\bin\\gimp-2.8.exe ";
    wchar_t test1[] = L"D:\\unbenannt.jpg"; 
    wcscat(test, test1);
    

    test ist gerade groß genug für den String, den du zum Initialisieren benutzt. Und dann hängst du noch was dran -> Bumm.



  • es tut mir leid, dass ich nochmal posten muss...

    weil ich brauch auf jedenfall normalen string,
    wie kann ich string in CreateProcess benutzen?

    string test = "blbalblaba.jpg"
    
    CreateProcessW(NULL, test, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    

    wirft nämlich folgenden fehler:
    Konvertierung des Parameters 2 von 'std::string' in 'LPWSTR' nicht möglich



  • Hallo,

    siehe dazu hier:

    http://www.c-plusplus.net/forum/274009

    Nachdem du dann auf MBCS umgestellt hast oder CreateProcessA verwendest, musst du test.c_str() statt nur test übergeben.

    MfG,

    Probe-Nutzer



  • Eigentlich wäre MBCS nicht wirklich richtig, sondern einfach Nichts (Not Set).
    Und std::string::c_str wird nichts helfen, denn CreateProcess will, wie bereits erwähnt, einen Pointer auf einen non const String, std::string::c_str liefert aber nur einen Pointer auf einen const String.



  • Naja... sagen wir mal so:
    Ich würde im Projekt nur Unicode verwenden. Somit muss der 2. Parameter schreibbar sein, sonst stürzt Dein Programm einfach ab.
    Wenn Du "Not Set" oder "MBCS" verwenden willst, so musst zwar laut Doku der zweite Parameter immer noch schreibar sein, aber es geht auch ohne, da intern ein eigenen Unicode-String angeleget wird und der übergebene (const) String nach Unicode umgewandelt wird. Dann wird der Aufruf an "(Nt)CreateProcessW" weitergeleitet; somit ist dann der zweite Parameter schreibbar und es stürzt nicht ab 😉



  • danke für eure antworten, aber mir hilft das jetzt überhaupt nicht weiter...

    es kann doch nicht sein das jedesmal wenn ich diese funktionen verwenden will, diese konvertierungsprobleme habe.

    es muss doch möglich sein diese funktion mit einem ganz normalen string aufzurufen sein?

    test.c_str() funktioniert nicht, hab ich schon versucht



  • lulu32 schrieb:

    es muss doch möglich sein diese funktion mit einem ganz normalen string aufzurufen sein?

    Jein

    lulu32 schrieb:

    test.c_str() funktioniert nicht, hab ich schon versucht

    Du brauchst in jedem Fall einen const_cast , da c_str() eben einen const char* liefert. Streng genommen gibt dir das aber Undefined Behavior, sobald du nichtmehr std::string und CreateProcessA verwendest. Ich würd davon abraten und mit der Unicode Variante CreateProcessW arbeiten, die eben einen modifizierbaren String als Parameter haben will. std::string als direkter Parameter fällt damit flach, welche Alternative im konkreten Fall am besten geeignet ist, hängt wie immer vom konkreten Fall ab. std::vector<wchar_t> wäre z.B. eine Möglichkeit...

    Jochen Kalmbach schrieb:

    Naja... sagen wir mal so:
    Ich würde im Projekt nur Unicode verwenden. Somit muss der 2. Parameter schreibbar sein, sonst stürzt Dein Programm einfach ab.
    Wenn Du "Not Set" oder "MBCS" verwenden willst, so musst zwar laut Doku der zweite Parameter immer noch schreibar sein, aber es geht auch ohne, da intern ein eigenen Unicode-String angeleget wird und der übergebene (const) String nach Unicode umgewandelt wird. Dann wird der Aufruf an "(Nt)CreateProcessW" weitergeleitet; somit ist dann der zweite Parameter schreibbar und es stürzt nicht ab 😉

    Ah stimmt, ist sogar dokumentiert, dass die ANSI Version den String nicht verändert...

    Ich persönlich verwend nur noch Unicode, wobei ich direkt mit den *W Varianten der entsprechenden APIs arbeite, da das ganze ANSI und UNICODE und TCHAR etc. Zeug imo heutzutage einfach nicht mehr interessant ist.



  • danke dot für deine antwort.

    CreateProcessA(NULL, const_cast<char*>(strtest.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    

    habe ich bereits probiert, damit ist der zweite string ok, aber dann kommt etwas mit dem ich garnichts anfangen kann

    Da sagt nicht mal mehr google was dazu:
    error C2664: 'CreateProcessA': Konvertierung des Parameters 9 von 'STARTUPINFO *' in 'LPSTARTUPINFOA' nicht möglich

    Hier nochmal der ganze code

    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
    si.wShowWindow = SW_SHOWNORMAL;
    
    PROCESS_INFORMATION pi;
    
    string strtest = "C:\\Program Files\\GIMP 2\\bin\\gimp-2.8.exe ";
    string strtestt = "D:\\unbenannt.jpg";
    
    strtest.insert(strtest.size(), strtestt);
    
    CreateProcessA(NULL, const_cast<char*>(strtest.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
    


  • Du musst natürlich auch explizit STARTUPINFOA verwenden, oder eben gleich für das ganze Projekt UNICODE abschalten.

    Aber wie gesagt: Ich persönlich würde den ANSI Kram vergessen und CreateProcessW verwenden...



  • CreateProcessW geht aber nicht, selbst mit cast nicht.

    und wenn ich wüsste wie ich STARTUPINFOA verwenden kann bei CreateProcessA dann hätte ich nicht gefragt. Es ist wirklich nur ein kleines Projekt und ich tu schon ewig rum, würde es halt einfach gern verstehen und wäre froh wenn es endlich mal funktionieren würde.

    wenn ich das projekt jetzt umstelle, dann kann es doch sein, dass ich woanderst wieder probleme bekomme.



  • Wo genau liegt das Problem? Du machst eben einfach STARTUPINFO si; zu STARTUPINFOA si; !?



  • ooohhh man bin ich ein gimp 😃

    ich hab LPSTARTUPINFOA benutzt (weil er das ja gebracht hat) und wundere mich warum es nicht geht... 🙂

    VIELEN DANK an alle und besonders an dot 🙂

    Jetzt hätte ich aber noch eine kleine Frage zum Verständnis. Würde mich freuen wenn du mir die beantwortest.

    1.Gibt es evtl. irgendwo Literatur mit Beispielen die, diese ganze Konvertierungsalgorithmen behandelt(finde leider nix)

    2. Was ist anderst wenn ich auf MBCS umstelle?



  • lulu32 schrieb:

    1.Gibt es evtl. irgendwo Literatur mit Beispielen die, diese ganze Konvertierungsalgorithmen behandelt(finde leider nix)

    Von was genau für "Konvertierungsalgorithmen" sprichst du?

    lulu32 schrieb:

    2. Was ist anderst wenn ich auf MBCS umstelle?

    Es werden andere Präprozessor Makros definiert. Dein konkretes Beispiel wird in seiner aktuellen Form davon allerdings kaum beeinflusst werden.



  • ich meine z.B. wo sowas const_cast<char*> behandelt wird.

    es gibt ja noch mehr sachen, string to char, cstring, char[], char*, TCHAR, wstring, LPTSTR usw... (ganz wirr durcheinander weil es so wirr in meinem kopf ist 🙂 )

    wie man halt das alles irgendwie hin und her bekommt.



  • Casts sind C++ Basics und werden in jedem guten Grundlagenbuch behandelt. const_cast ist jedenfalls nur in den seltensten Fällen tatsächlich eine gute Idee. In diesem Fall hier ist es imo ein hässlicher Hack und relativ grenzwertig, allerdings ist es einer der seltenen Fälle, wo der const_cast zumindest nicht direkt einfach nur falsch ist...

    char, char[] und char* sind Basics, string und wstring sind Teil der Standardbibliothek, TCHAR ist ein typedef, das je nachdem ob UNICODE definiert ist oder nicht dem passenden Typ entspricht (WCHAR oder char), LPTSTR ist ein typedef und entspricht einem TCHAR* (Long Pointer to TCHAR STRing, siehe auch hier)...



  • danke für die antwort, aber das ist mir soweit schon klar was es ist...

    nur wenn man wieder funktionen nutzen will und dann den ganzen käse umwandeln muss, da kommt mir immer das grauen...


Anmelden zum Antworten