Monday 19 December 2016

Waitforexit Process C # Example Programs

Utilizo Process. Start para iniciar un archivo por lotes. El archivo por lotes utiliza el comando START para iniciar varios programas en paralelo y luego sale. Una vez que el archivo por lotes se hace Process. HasExited se convierte en verdadero y Process. ExitCode contiene el código de salida correcto. Pero cuando llamo Process. WaitForExit () cuelga / nunca vuelve. El siguiente código muestra el problema. Crea un archivo por lotes, lo inicia y luego imprime: Debería imprimir: pero nunca lo hace (aunque HasExited es verdadero y ya tenemos un ExitCode). Me di cuenta de que esto sólo ocurre cuando el archivo por lotes contiene comandos START y cuando la salida estándar y / o el error estándar son redirigidos. ¿Por qué WaitForExit () nunca devuelve ¿Cuál es la forma correcta de esperar a que se cierre un proceso de este tipo Es seguro probar Process. HasExited o puede resultar en otros problemas PS. Acabo de notar que llamar a WaitForExit (100000) con un tiempo de espera enorme (que definitivamente no caduca) vuelve inmediatamente cuando sale el proceso. Extraño Sin tiempo de espera se cuelga. Hay una diferencia fundamental cuando se llama WaitForExit () sin un tiempo de espera, se asegura de que el stdout / err redireccionado han devuelto EOF. Esto asegura que usted haya leído toda la salida que fue producida por el proceso. No podemos ver lo que quotonOutputquot hace, pero las probabilidades altas que impide su programa, ya que hace algo desagradable como asumir que su hilo principal está inactivo cuando está realmente atrapado en WaitForExit (). Ndash Hans Passant Nov 3 14 at 12:06 Esto parece ser un artefacto (Id decir error) en la implementación específica del manejo asíncrono basado en eventos de StandardOutput y StandardError. Me di cuenta de que mientras que era capaz de reproducir fácilmente su problema, simplemente por ejecutar el código que proporcionó (ejemplo de código excelente, por cierto.)), El proceso realmente no cuelga indefinidamente. Más bien, regresó de WaitForExit () una vez que ambos de los procesos secundarios que se habían iniciado habían salido. Esto parece ser una parte intencional de la implementación de la clase Process. En particular, en el método Process. WaitForExit (), una vez que ha terminado de esperar en el identificador de proceso en sí, comprueba si un lector para stdout o stderr se ha creado si es así y si el valor de tiempo de espera de WaitForExit ) Es infinita (ie -1), el código realmente espera el final de la corriente en el lector (s). Cada lector respectivo se crea sólo cuando se llama al método BeginOutputReadLine () o BeginErrorReadLine (). Las corrientes stdout y stderr no están cerradas hasta que los procesos del niño se han cerrado. Así que esperar al final de esos arroyos se bloqueará hasta que eso suceda. Que WaitForExit () debería comportarse de forma diferente dependiendo de si uno ha llamado cualquiera de los métodos que inician la lectura basada en eventos de los flujos o no, y especialmente dado que la lectura de esos flujos directamente no causa WaitForExit () comportarse de esa manera, crea Una inconsistencia en el API que hace que sea mucho más difícil de entender y usar. Aunque Id personalmente llamar a esto un error, supongo que es posible que el implementador (s) de la clase de proceso son conscientes de esta inconsistencia y creado a propósito. En cualquier caso, la solución sería leer StandardOutput y StandardError directamente en lugar de utilizar la parte basada en eventos de la API. (Aunque, por supuesto, si los códigos de código de esperar en los arroyos, uno vería el mismo comportamiento de bloqueo hasta que el niño los procesos de cierre.) Por ejemplo (C, porque no sé F bien lo suficiente para dar un ejemplo de código así rápidamente juntos :)): Esperemos que el trabajo anterior alrededor o algo similar se ocupará de la cuestión básica youve ejecutar en. Mi agradecimiento al comentarista Niels Vorgaard Christensen por dirigirme a las líneas problemáticas del método WaitForExit (), para poder mejorar esta respuesta. Estoy escribiendo una aplicación donde hay dos llamadas a programas externos, RichCopy y 7zip. La idea es usar RichCopy para mover archivos y 7zip para archivar y cifrar los archivos una vez que termine RichCopy. El problema que tengo es que la aplicación no está esperando que RichCopy termine de mover archivos antes de que 7zip intente archivarlos a pesar del hecho de que estoy usando WaitForExit. El código está abajo: Así que RichCopy arranca, pero inmediatamente después de ver la pantalla de bienvenida para RichCopy 7zip comienza a archivar y cifrar una carpeta vacía. ¿Hay algo que me falta o es el método WaitForExit () se supone que esperar hasta que el proceso termina antes de pasar a la siguiente línea de código solicitado Sep 23 14 at 12:11 Pruebe lo siguiente: en lugar de voic filecopy (), el proceso de devolución. El proceso que devuelve es f1. En encryptdata, agregue un argumento de proceso y establezca esto en el proceso que devuelve desde filecopy. A continuación, en encryptdata, espere a que finalice el proceso antes de iniciar el proceso de cierre. Lo que creo que está ocurriendo es que WaitForExit en filecopy por alguna razón es no bloqueante. O su optimizado lejos porque theres nada detrás de él, o él espera, pero la línea siguiente de la función que llama está comenzada de todos modos. Otra posibilidad es que tu filecopy inicie RichCopy con argumentos mal formados, lo que hace que salga temprano (ya sea porque no hace nada o porque devuelve un error). Intente ejecutar filecopy por separado para ver si funciona correctamente y hace lo que espera. Respondió Sep 23 14 at 12:25 Gracias Nate - I39ll dar estas sugerencias un intento. Intenté aislar la parte de la copia del archivo del programa y que está trabajando como esperado. Cuando ejecuto el programa por segunda vez, 7zip realmente ve los archivos previamente movidos de la primera ejecución y los archiva / cifra como esperado también, pero no puedo esperar que RichCopy termine. Ndash Luke Smith Sep 23 14 at 12:31 Para cualquier persona que se encuentra con esta pregunta en el futuro, lo que acabé haciendo fue envolver un bucle de tiempo alrededor de un cheque para ver si el proceso de RichCopy64 todavía estaba en ejecución. Si todavía estaba funcionando, le dije que esperara 10 segundos, luego vuelva a intentarlo. Gracias a todos los que respondieron - cuando tengo suficiente representante Ill estar seguro de upvote sus respuestas. Estoy luchando contra un estúpido par de líneas de código con resultados muy extraños. Estoy corriendo Win7. El objetivo es iniciar un archivo de comandos (.cmd) de un programa y esperar a que este. cmd termine (con tiempo de espera). Dentro del archivo. cmd, hay un comando TASKKILL. TASKKILL / F / T / IM CI. EXE Funciona perfectamente. Pero. Si se muestra la pantalla de inicio de sesión (el usuario ha iniciado sesión, pero la sesión está bloqueada), TASKKILL está funcionando, pero WaitForExit nunca finaliza, incluso después de un tiempo de espera. ¿Hay alguna buena explicación para esto y una sugerencia de solución. Gracias de antemano Viernes, 08 de abril 2016 7:52 AM Respuestas Gracias por su tiempo y sugerencia. Al final, decidí reescribir mi propio TASKKILL con un código C muy sencillo, basado en: foreach (Proceso proc en Process. GetProcessByName (quotCIquot)) (Ci es el nombre del proceso que quiero matar) Y milagro. funciona. Por lo tanto, Im en el camino pensando TASKKILL hace mucho más que matar a un proceso. De hecho, mi error ahora está arreglado, así que estableceré el hilo como contestado. Gracias por su lectura Marcado como respuesta por dt51 Viernes, 08 de abril 2016 2:42 PM Viernes, 08 de abril 2016 2:42 PM Todas las respuestas Estoy asumiendo que el tiempo de espera significa que usted está definiendo un tiempo para esperar la salida del proceso. Si es así, por favor, intente dejar el proceso de auto salir. En lugar de esperar un cierto período de tiempo. Editado por Sabah Shariq Moderador Viernes 08 de Abril de 2016 10:01 Viernes, 08 de abril de 2016 9:59 Gracias por su tiempo y respuesta. Por desgracia, no funciona. Estoy en la idea de que el TASKKILL va a hacer alguna perturbación en el método Process. WaitForExit. De hecho, ambos están trabajando en la misma área. Im va a crear mi propia versión de TASKKILL de C, pero Im no tan optimista. Te haré saber. Si tienes otra idea, serás bienvenido Friday, April 08, 2016 10:53 AM Si se muestra la pantalla de inicio de sesión (el usuario ha iniciado sesión, pero la sesión está bloqueada), TASKKILL está funcionando, pero WaitForExit no termina nunca, incluso después del tiempo de espera . Tiene que ser en su mayoría adivinar aquí. Además de los estados elevados / no elevados, también existe el concepto de una sesión interactiva / no interactiva. ¿Cuál es el contexto exacto en el que se está ejecutando el código bajo Process. WaitForExit () tiene esta pequeña advertencia: quotEste método instruye al componente Process a esperar una cantidad infinita de tiempo para que los manejadores de procesos y eventos salgan. Esto puede hacer que una aplicación deje de responder. Por ejemplo, si llama a CloseMainWindow para un proceso que tiene una interfaz de usuario, la solicitud al sistema operativo para finalizar el proceso asociado puede no ser manejada si el proceso está escrito para nunca introducir su bucle de mensaje. El escritorio está bloqueado (el usuario no ha iniciado sesión correctamente), no hay sesión interactiva. O tal vez ninguno de los bucles de mensajes responden de forma predeterminada, ya que procesarlos sólo costaría recursos de la CPU. O tal vez al revés: no tener una sesión interactiva para empezar podría permitir que el programa continuara ejecutándose. Es que el código se ejecuta en un servicio Si no, ¿qué tal si se mueve allí Viernes, 08 de abril 2016 11:35 Gracias por su tiempo y sugerencia. Al final, decidí reescribir mi propio TASKKILL con un código C muy sencillo, basado en: foreach (Proceso proc en Process. GetProcessByName (quotCIquot)) (Ci es el nombre del proceso que quiero matar) Y milagro. funciona. Por lo tanto, Im en el camino pensando TASKKILL hace mucho más que matar a un proceso. De hecho, mi error ahora está arreglado, así que estableceré el hilo como contestado. Gracias por su lectura Marcado como respuesta por dt51 Viernes, 08 de abril de 2016 2:42 PM Viernes, 08 de abril de 2016 14:42 Microsoft está realizando una encuesta en línea para entender su opinión sobre el sitio Web Msdn. Si decide participar, se le presentará la encuesta en línea cuando abandone el sitio Web de Msdn. ¿Quieres participar? Ayúdanos a mejorar MSDN. Visite nuestra página UserVoice para enviar y votar ideas Centros de desarrollo Recursos de aprendizaje Programas de apoyo comunitario


No comments:

Post a Comment