2010-02-27 5 views
11

Quiero convertir WinMain' s cmdLine argumento para argc y argv para que pueda utilizar la función de análisis de argumentos que escribí para aplicaciones de consola.Romper cmdLine de WinMain en las principales viejo estilo() 's argumentos

Esto sería trivial, excepto que también quiero admitir "presupuestos". Por ejemplo:

test.exe test1 test2 "testing testing"

debería ser

argv[0] = "test.exe"; argv[1] = "test1"; argv[2] = "test2"; argv[3] = "testing testing"; 

que darse cuenta de que cmdLine no tiene el nombre del programa (argv [0]); esto no importa, puedo usar un valor ficticio.

Estaba pensando en hacerlo con una expresión regular, (("[^"]+")\s+)|(([^\s]+)\s*) No estoy seguro de lo bien que funcionaría aunque ... ¿Probablemente no muy bien? ¿Hay alguna función para hacer eso en la API de Windows? Gracias

Respuesta

5

CommandLineToArgvW parece que sería útil aquí.

+1

simplemente ver que 'CommandLineToArgvW' doesn' t agrega un valor NULL de centinela al final de la matriz, por lo que no tiene la misma semántica que 'argv' en la norma C. – jamesdlin

+2

Además,' CommandLineToA rgvW' no expandirá globs. Si '__argc' /' __argv' no están disponibles, debe usar '__getmainargs' o' __wgetmainargs' en su lugar. –

+0

@AndrewMedico ¿Desde C89? El estándar de lenguaje exige que "' argv [argc] 'sea un puntero nulo". Si bien es información redundante, es un comportamiento estándar, por lo que algunas personas confían en eso. – jamesdlin

20

Si está utilizando Microsoft compilador, no son símbolos públicos __argc, __argv y __wargv definido en stdlib.h. Esto también se aplica a MinGW que usa las bibliotecas de tiempo de ejecución de Microsoft.

+5

+1. Cuando estos están disponibles, yo personalmente prefiero estos sobre 'CommandLineToArgvW' ya que no tiene que hacer una llamada a' LocalFree' y dado que '__argv [__argc]' y '__argv [__argc]' están establecidos en 'NULL'. – jamesdlin

+0

¡Fantástico! ¿Pero qué hay de 'envp'? ** EDITAR **: Ok, '_CRTIMP extern char ** environ;' hace el truco, creo. – csl

1

Si quiere argumentos simples de tipo arc, char ** argv, tiene que hacerlo por su cuenta.

void fetchCmdArgs(int* argc, char*** argv) { 
    // init results 
    *argc = 0; 

    // prepare extraction 
    char* winCmd = GetCommandLine(); 
    int index = 0; 
    bool newOption = true; 
    // use static so converted command line can be 
    // accessed from outside this function 
    static vector<char*> argVector; 

    // walk over the command line and convert it to argv 
    while(winCmd[index] != 0){ 
     if (winCmd[index] == ' ') { 
      // terminate option string 
      winCmd[index] = 0; 
      newOption = true; 

     } else { 
      if(newOption){ 
       argVector.push_back(&winCmd[index]); 
       (*argc)++; 
      } 
      newOption = false; 
     } 
     index++; 
    } 

    // elements inside the vector are guaranteed to be continous 
    *argv = &argVector[0]; 
} 


// usage 
int APIENTRY WinMain(...) { 
    int argc = 0; 
    char** argv; 
    fetchCmdArgs(&argc, &argv); 
} 
+1

-1 es mucho más complicado de lo que parece. Por un lado, no estás manejando citas. – Mehrdad

1

Basado en la respuesta Denis K

Ver: https://msdn.microsoft.com/library/dn727674.aspx

Esto se suma a punto de entrada específico de Windows clásico punto de inicio de la aplicación:

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd) 
{ 
    return main(__argc, __argv); 
} 
Cuestiones relacionadas