c# - argumentos - ¿Qué hace exactamente System.Diagnostics.Process UseShellExecute?
msbuild project (4)
¿Ha especificado WorkingDirectory correctamente? Puede ver el resultado real de su comando agregando >c:/log.txt 2>c:/err.txt
ejecutándolo en esta adición y verifique esos archivos
Tengo una tarea de MSBuild que ejecuta (entre otras cosas) una llamada a xcopy. Lo que he descubierto es que esta llamada a xcopy se ejecuta correctamente cuando ejecuto mi tarea MSBuild desde un archivo por lotes, y no ejecuta ni produce ningún resultado que me permita saber qué ocurre cuando se llama a ese mismo archivo por lotes Aplicación C # con un System.Diagnostics.Process.
Ambos procesos se lanzan con más o menos la misma estructura:
waitProc.StartInfo.Arguments = "/C [executable]";
waitProc.StartInfo.FileName = "cmd.exe";
waitProc.StartInfo.UseShellExecute = false;
Además, al cambiar "UseShellExecute" de falso a verdadero en el comando xcopy, puedo hacer que esto tenga éxito en ambos casos de uso, sin embargo, el comando no se ejecuta en un tercer caso de uso. El tercer caso de uso es nuestro sistema de compilación automatizado que es un servicio de Windows que llama a msbuild directamente. En el caso de la falla en nuestra máquina de compilación, el comando de copia se bloquea indefinidamente, lo cual es, creo, porque el Sistema.Diagnostics.Process intenta mostrar una ventana, y los servicios no tienen una sesión de escritorio de Windows asociada, por lo que no pueden ventanas de visualización
He intentado usar la propiedad "CreateNoWindow" y he intentado configurar "WindowStyle" en "ProcessWindowStyle.Hidden", pero eso no cambia el comportamiento en la máquina de compilación.
Dicho todo esto, lo que realmente quiero saber es qué hace exactamente la propiedad UseShellExecute, porque parece hacer mucho más de lo que sugiere la documentación de MSDN.
Gracias.
De la ProcessStartInfo.UseShellExecute :
Establecer esta propiedad en falso le permite redirigir las secuencias de entrada, salida y error.
Nota: UseShellExecute debe ser falso si la propiedad UserName no es una referencia nula (Nothing en Visual Basic) o una cadena vacía, o se lanzará una InvalidOperationException cuando se llame al método Process.Start (ProcessStartInfo). Cuando utiliza el shell del sistema operativo para iniciar procesos, puede iniciar cualquier documento (que es cualquier tipo de archivo registrado asociado con un ejecutable que tiene una acción de apertura predeterminada) y realizar operaciones en el archivo, como la impresión, con el componente Proceso. Cuando UseShellExecute es falso, solo puede iniciar archivos ejecutables con el componente Proceso.
Nota: UseShellExecute debe ser verdadero si establece la propiedad ErrorDialog en verdadero. La propiedad WorkingDirectory se comporta de manera diferente cuando UseShellExecute es verdadero que cuando UseShellExecute es falso. Cuando UseShellExecute es verdadero, la propiedad WorkingDirectory especifica la ubicación del ejecutable. Si WorkingDirectory es una cadena vacía, se entiende que el directorio actual contiene el ejecutable.
Cuando UseShellExecute es falso, la propiedad WorkingDirectory no se usa para encontrar el ejecutable. En su lugar, es utilizado por el proceso que se inicia y tiene un significado solo dentro del contexto del nuevo proceso.
El uso de ''UseShellExecute'' IIRC, es permitir que el explorador (el shell principal) ejecute el proceso y no el tiempo de ejecución .NET ... a menos que alguien me corrija que estoy equivocado ...
ProcessStartInfo.UseShellExecute le dice al Proceso que use el Shell de Windows para ejecutar la aplicación especificada.
Sin este conjunto, solo puede ejecutar un archivo EXE directamente. Al configurar esto, permite que se use el Shell de Windows, lo que permite cosas como especificar un archivo .doc y hacer que el programa asociado abra el archivo.
Sin embargo, usar el Shell de Windows requiere un contexto de escritorio válido, por lo que su tercer caso de uso falla.
En general, usar cmd.exe
es problemático a menos que esté usando el Shell de Windows. Es posible que desee simplemente escribir el código para manejar su operación de "lote" directamente, es decir: utilice los métodos de los tipos en el espacio de nombres System.IO para hacer su copia. Esto evitaría este problema por completo.