2009-06-10 15 views
5

Estoy escribiendo un programa (Win32 Console) que envuelve otro proceso; que toma los parámetros como en el siguiente ejemplo:Convirtiendo argv en una sola cadena

runas.exe user notepad foo.txt 

Esto es: runas análisis sintáctico de user y luego se ejecutará bloc de notas, pasando los parámetros restantes.

Mi problema es que argv se divide en parámetros individuales, pero CreateProcessAsUser requiere un solo parámetro lpszCommandLine.

Construir esta línea de comando probablemente no sea tan simple como unir argv con espacios. ¿Alguna sugerencia?

Esto es solo un ejemplo. Mi primer argumento no es realmente un nombre de usuario, y podría tener espacios en él. Esto hace que el análisis manual del resultado de GetCommandLine sea complicado.

De forma similar, una concatenación ingenua de argv no funcionará, porque debe tratar el caso en el que se citaron los argumentos originales y pueden tener espacios en ellos.

+1

diría "argv unirse de nuevo juntos con espacios" estaría bien. ¿Qué te hace pensar lo contrario? –

+0

Benoît, porque no funcionaría para el bloc de notas del usuario 'runas.exe' foo bat.txt ''. – avakar

+3

No olvides citar cualquier args que contenga espacios – Hasturkun

Respuesta

7

recombinación de forma manual es difícil:

Se podría tratar de volver a combinarlas, yo creo que funcionaría, pero asegúrese de seguir the same command line escaping rules that windows has. Esto podría ser más que la solución trivial que está buscando.

Además, si hay algún parámetro que tenga espacios en ellos, querrá unirlos a la cadena con comillas alrededor de ellos. Aquí hay un ejemplo de una extraña regla de escape: si tiene --folderpath "c:\test\", entonces la última barra invertida tiene que duplicarse --folderpath "c:\test\\".

Si está utilizando MFC:

Puede puede obtener el valor que desea de su derivada theApp.m_lpCmdLine de CWinApp. Tenga en cuenta que aún puede acceder a ellos de la otra manera con __argc, y __argv o CommandLineToArgvW.

Si está utilizando Win32 solamente (incluso sin una interfaz gráfica de usuario):

Puede obtenerlo de WinMain. Que puede ser el punto de entrada de tu programa.

Tenga en cuenta que todavía podría acceder a ellos de la otra manera con __argc, y __argv o CommandLineToArgvW.

Si tiene que usar una aplicación basada en consola con principal o wmain:

La API de Win32 GetCommandLine parece ser el camino a seguir. Sin embargo, necesitaría analizar esto para obtener el nombre .exe. Tenga en cuenta las cotizaciones alrededor del nombre/ruta del exe también. Si no hay tales comillas al principio, simplemente diríjase al siguiente espacio para el comienzo.

+0

Argv concatenante con espacios parece funcionar; si argv [i] contiene un espacio, cito ese valor particular. He intentado un par de casos extremos obvios, y se ve bien hasta ahora. –

+0

Aquí hay una discusión sobre el lío que escapa de la línea de comandos en Windows: http://blogs.msdn.com/b/twistylittlepasagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way. aspx –

2

Puede usar la función GetCommandLine.

¿Por qué no utilizar 'WinMain' en lugar de 'main'? Esto debería darle la cadena en el formato que desee.

+2

El resultado de la llamada GetCommandLine debe procesarse antes de pasarse a la próxima llamada CreateProcess. El primer argumento debe ser eliminado. Tenga cuidado de que el nombre del programa pueda ser envuelto con comillas dobles. – hvintus

+0

En este caso particular, los dos primeros argumentos deben eliminarse: el nombre del ejecutable y también el nombre de usuario. –

0

Siempre que tenga una cadena asignada con suficiente espacio, utilice strcat en cada elemento de la lista. Sí, es tan simple como unirlos de nuevo con espacios.

Editar: Por supuesto, debe encerrar cualquier elemento que contenga espacios entre comillas.

+0

-1, no, no es tan simple. – avakar

+0

Para su ejemplo, sí lo haría. La advertencia de rodear cualquier elemento que contenga espacios con comillas lo verá en este ... – Xetius

1

Hay Win32 llamada a la API que devuelve la línea de comandos: GetCommandLine

Cuestiones relacionadas