c# - sorteo - ¿Cómo sortear el límite de longitud de la línea de comando?
sortea2 (9)
He estado trabajando en un programa pequeño y sencillo en el que coloco archivos y, según las normas de Certian, se trasladan a diferentes lugares.
El programa funciona bien a menos que suelte más de unos pocos archivos, luego se elimina un error (que parece ser más de Windows que cualquier otra cosa) que el comando de inicio "c: / myapp.exe / file / file / file" también es largo.
Me doy cuenta de que podría establecer un proceso en segundo plano, pero realmente preferiría que este programa no se ejecute en segundo plano (donde estaría inactivo la mayor parte del tiempo).
¿Hay alguna forma de evitar esta limitación?
¿Cómo sortear el límite de longitud de la línea de comando? Escriba todo su comando en un archivo por lotes, por ejemplo, en "C: / Users / Johnny / Documents / mybatch.bat". Escríbelo como lo haría en el cmd (no hay necesidad de escapar de nada). Luego, en su código simplemente llame a ese archivo:
strCmdText = "C://Users//Johnny//Documents//mybatch.bat";
ProcessStartInfo ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + strCmdText);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = true;
Process.Start(ProcessInfo);
Creo que el controlador de arrastrar y soltar es posiblemente un camino a seguir, pero parece bastante pesado.
Una solución alternativa es utilizar un controlador del menú contextual de Explorer. Con esto en su lugar, seleccionaría todos los archivos, pero en lugar de arrastrarlos, haga clic derecho y elija su nuevo elemento de menú "Enviar a".
Cuando se selecciona el elemento del menú, pasa la lista de comandos a su programa. Hay un par de maneras de hacer esto:
- inicie su programa y alimente la lista de archivos a la entrada estándar
- escriba la lista de archivos en un archivo temporal e inicie su programa con un solo argumento de comando: el archivo temporal que enumera los archivos para procesar. Los archivos de lista usualmente tienen el prefijo ''@'' en la línea de comando para distinguirlos de los nombres de archivos comunes.
Creo que la solución más sencilla es modificar su aplicación para aceptar un directorio como parámetro en lugar de una lista de archivos. Esto le permitiría copiar los archivos múltiples en un solo directorio. Luego puedes arrastrar y soltar la carpeta en tu ejecutable. Luego ejecutaría un comando como "c: / myapp.exe / folder-with-files-in-it" que no debería coincidir con la limitación de parámetros de la línea de comandos que está experimentando ahora.
Cuando los archivos se arrastran y se sueltan en su aplicación, escriba la lista de nombres de los archivos en un archivo de texto y luego asigne la ubicación de este archivo a su programa. El programa de destino puede leer este archivo y procesarlo línea por línea. De esta manera solo se pasa un solo nombre de archivo.
De este blog :
- La longitud máxima de la línea de comando para la función CreateProcess es 32767 caracteres. Esta limitación proviene de la estructura UNICODE_STRING.
- Si está utilizando el procesador de comando CMD.EXE, también está sujeto al límite de longitud de línea de comando de 8192 caracteres impuesto por CMD.EXE.
- Si está utilizando la función ShellExecute / Ex, queda sujeto al límite de longitud de línea de comando de INTERNET_MAX_URL_LENGTH (alrededor de 2048) impuesto por las funciones ShellExecute / Ex.
- El tamaño máximo de su entorno es de 32767 caracteres. El tamaño del entorno incluye todos los nombres de variables más todos los valores.
Así que tendrás que resolver algunas de las soluciones mencionadas (también, hay otra solución en el blog msdn que vinculé).
Experimenté un problema similar cuando intentaba obtener detalles de seguridad en un camino largo. Mi solución fue asignar unidades cuando la longitud del camino fuera demasiado larga. Revise mi solución en ¿Cómo obtengo los detalles de seguridad para un camino largo?
Los comandos de Unix frecuentemente tienen uno o dos parámetros que pueden ser de longitud ilimitada. Varios de estos comandos han agregado parámetros que pueden generar esos argumentos desde un archivo o desde una entrada estándar. Así que tienes un comando que abre la lista de argumentos y los canaliza a un archivo temporal, o los canaliza a la salida estándar.
Vea también, xargs, que puede tomar una lista de argumentos e invocar su comando con todos los parámetros, o en lotes.
Modificaría la aplicación para recoger los archivos de una ubicación específica (por ejemplo, una carpeta específica en un sistema de archivos) en lugar de especificar cada archivo en la línea de comandos.
ACTUALIZAR:
Si el requisito es poder arrastrar un elemento a un archivo .exe a través del Explorador de Windows para iniciar la aplicación, tal como Mark lo mencionó, usted podría poner todos sus archivos en una carpeta y soltar toda la carpeta en el archivo .exe.
Si desea eliminar los archivos con respecto al Explorador de Windows, puede implementar sus propios manejadores Drop como controladores de extensión de Shell (consulte http://msdn.microsoft.com/en-us/library/cc144165(VS.85).aspx y http://msdn.microsoft.com/en-us/library/bb776797.aspx ). En http://www.codeproject.com/kb/shell/shellextguideindex.aspx encontrará una buena introducción sobre cómo escribir dichas extensiones. La parte VI (ver http://www.codeproject.com/kb/shell/ShellExtGuide6.aspx ) da un ejemplo de Drop Handler (para un poco más de otro caso de uso, pero no importa la dosis).
Con respecto a Drop Shell Extension Handler, su programa recibirá información completa sobre todos los archivos eliminados y no necesita iniciar un programa secundario con todos los archivos como parámetros similares a comandos.