CreateProcess() unter 64bit und unformatierte Argumente unter C++

ntor

Stammuser
Hey Leute!
Ich stehe vor ein paar Fragen/Problemen für die ich keine Erklärung finde.

1.) In meinem Suchprogramm habe ich die Option , statt Dateien alá X:\... anzuben auch die Option einen Befehl zu durchsuchen. Ich hab das jetzt einfach mit einer temporären Datei gemacht. Wenn ich die temporäre Datei aber mit CreateProcess() erstellen/füllen will , dann schlägt das Programm immer mit EC=2 fehl ("The system cannot find the file specified"). Ich hab das Kommando auch einmal alleine ausgeführt. Funktioniert! Momentan überbrücke ich das einfach mit system() , was mich aber nicht ganz zufrieden stellt. Wobei auszuschließen ist , dass ich Code-Fehler habe , da selbst das Originale msdn-Beispiel gleich missschlägt.

2.) Das zweite Problem besteht darin , dass ich meine Kommandos z.B. in der Form --command:"dir \" übergebe. Da C/C++ aber anscheinend argv mit sprintf() füllt wird aus "dir \" nicht dir \ , sondern dir ". Und spätestes dann wird es schwierig zurückzuverfolgen , wenn man z.b. "dir C:\dings\xFF" angibt. Ich will mich auch nicht zufriedengeben , alles mit '\\' zu schreiben. Gibt es da einen Weg die Formtierung zu deaktivieren?

Herzliche Grüße
nt0r

PS: Wie kann man sein Programm dazu bringen Output eines Programms zu durchsuchen in Form von "strings |myfind "Fail!"" ? Bzw. Woher würde das Programm wissen , dass es mit einem Pipe aufgerufen wurde? Oder sind das nur Betriebssystespezifische Befehle?
 

bitmuncher

Senior-Nerd
PS: Wie kann man sein Programm dazu bringen Output eines Programms zu durchsuchen in Form von "strings |myfind "Fail!"" ? Bzw. Woher würde das Programm wissen , dass es mit einem Pipe aufgerufen wurde? Oder sind das nur Betriebssystespezifische Befehle?

Pipes sind immer betriebssystemspezifisch. Unter Unix/Linux werden dafür Nodes und Fifos genutzt also das Dateisystem, während MSDN auf eine Client-Server-Architektur setzt. Die Pipe wird also unter Unix/Linux im Dateisystem abgelegt, worauf dann der Server und der Client zugreifen. Unter Windows wird dafür ein Socket-Prinzip genutzt.

Da ich mit Windows/MSDN nicht code (ich stehe nicht sonderlich auf Masochismus ;) ), kann ich dir allerdings bei deinen anderen Problemen nicht helfen. Ich würde aber mal tippen, dass du um entsprechende Escape-Sequenzen nicht herumkommen wirst.
 

ntor

Stammuser
Sodelle

Ich würde aber mal tippen, dass du um entsprechende Escape-Sequenzen nicht herumkommen wirst.

Mit der C/C++ StandardLib leider schon. Aber Ich hab ne schöne Win32 Funktion gefunden.
Und hier hab ich schnell (*hust* :D) mal ne Funktion gebastelt um dies unformatiert in ein typisches argv zu verwandeln. (Achja der Name ist schrecklich :rolleyes:)
Code:
inline char * pushback_atqmark(char *ptr)
{
    char *tmp_ptr=NULL;
    *ptr=*(ptr+1);
    while(*ptr)
    {
        *ptr++=*(ptr+1);
        if(*ptr=='\"')
            tmp_ptr= (tmp_ptr == NULL) ?ptr-1 :tmp_ptr;
    }

    for(ptr=tmp_ptr; *ptr; ptr++)
                *ptr = *(ptr+1);
    return tmp_ptr;
}

char ** CmdLineToUnformArgv(char *cmd_line,int *to_argc)
{
    char **argv = NULL;

    for(*to_argc=0 ; *cmd_line; (*to_argc)++)
    {
        argv = (char **) realloc(argv,((*to_argc)+1) * sizeof(char *));
        argv[*to_argc]=cmd_line;
        for( ; *cmd_line; cmd_line++)
        {
            if(*cmd_line == '\"')
                cmd_line = pushback_atqmark(cmd_line);

            if(*cmd_line ==' ')
            {
                while(*cmd_line == ' ')
                    *cmd_line++ = '\0';
                break;
            }
        }
    }
    return argv;
}

Herzliche Grüße
nt0r

PS: Bitte nur konstruktives zu meinem Programmierstil. Code noch nicht sehr lange.

EDIT: Wenn jemand das unter Linux machen will muss er die CmdLine nicht aus einer Funktion ziehen , sondern kann sie direkt aus der Pseudo-File \proc\self\cmdline abzapfen.
 
Zuletzt bearbeitet:
Oben