Tuesday, December 27, 2016

Waitforexit Processed

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 true 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 para 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 en el método WaitForExit (), para que yo pudiera mejorar esta respuesta. Estoy tratando de ejecutar un programa de PowerShell, esperar a la salida, a continuación, obtener acceso a la ExitCode, Pero no tener mucha suerte. No quiero usar - Wait con Start-Process, ya que necesito algún procesamiento para continuar en el fondo. Heres un script de prueba simplificado: Ejecutar este script hará que notepad se inicie. Después de que se cierra manualmente, se imprimirá el código de salida y se iniciará de nuevo sin utilizar - wait. No se proporciona ExitCode cuando esto está cerrado: Tengo que poder realizar procesamiento adicional entre iniciar el programa y esperar a que lo deje, así que no puedo hacer uso de - Wait. Cualquier idea de cómo puedo hacer esto y aún tener acceso a la propiedad. ExitCode de este proceso se preguntó Apr 21 12 at 19:23 Hay dos cosas a recordar aquí. Uno es agregar el argumento - PassThru y dos es añadir el argumento - Wait. Es necesario añadir el argumento de espera debido a este defecto connect. microsoft/PowerShell/feedback/details/520554/start-process-does-not-return-exitcode-property Una vez hecho este objeto de un proceso se pasa de nuevo y se puede ver En la propiedad ExitCode de ese objeto. Aquí está un ejemplo: Si lo ejecuta sin - PassThru o - Wait, no imprimirá nada. Estoy trabajando en un programa que actúa como un instalador para varios programas. Mi programa simple ejecuta otros programas de instalación como procesos desde C. Estaba tratando de usar el evento process. Exited para desencadenar el siguiente paso de la instalación, pero este evento nunca parece ser activado incluso cuando los procesos están terminados y se termina Alguien sabe por qué esto es y una solución a la misma. Necesito una forma de controlar los diferentes pasos de una manera lineal y evitar que varios procesos se ejecuten simultáneamente. Utilizaría el método de. WaitForExit () pero esto evita que mi forma de las ventanas de refrescar y poner un diverso objeto encima de lo haga parecer que la forma no está respondiendo. Gracias por la ayuda Lunes 20 de Marzo de 2006 22:04 Respuestas Intenta establecer la propiedad Process. EnableRaisingEvents como verdadera. Martes 21 de Marzo de 2006 4:40 AM Es porque los eventos se están ejecutando en otro hilo que tiene que empujar las llamadas de nuevo al hilo principal usando control. invoke () weblogs. asp. net/justinrogers/articles/126345. Aspx incluye una explicación detallada. Martes, 21 de marzo de 2006 7: 27 PM Todas las respuestas Intente establecer la propiedad Process. EnableRaisingEvents como true. Martes 21 de Marzo de 2006 4:40 Gracias por la punta Martes 21 de Marzo de 2006 3:18 PM Esa línea de código que me diste permite que los eventos se activen pero también ha causado algunos otros problemas Después de que el evento ha sido No puedo cambiar ninguna de las propiedades de los objetos de formulario. Dice que fueron creados en otro hilo. Estoy utilizando un P4 con hyperthreadign pero no he sido doin cualquier programación de hilo. He intentado ejecutar el programa con CheckForIllegalCrossThreadCalls falso el programa podría funcionar pero cuando intenté abrir una nueva forma del funtion del acontecimiento (o de una función llamada por la función del acontecimiento) la forma no cargaría correctamente y dejaría de responder Cualquier persona tiene ideas Lo que está causando esto y lo que los procesos tienen que ver con ello. Martes, 21 de marzo de 2006 16:09 Estoy teniendo el mismo tipo de problema. Tengo un formulario con un botón y una barra de progreso. Estoy utilizando Process. Start () para dos (2) procesos bajo el evento buttonClick (). Lo que quiero hacer es mostrar el estado a través de progrssbar después de cada proceso se ha completado. Estoy utilizando WaitForExit () para que el proceso salga. Sin embargo, la barra de prusión no se actualiza después de cada llamada a Process. Start (). Parece que el formulario principal pierde el foco cuando se inicia un proceso y nunca se recupera hasta que se completan todos los procesos. He intentado this. Active () en el formulario después de WaitForExit (), no funcionó. PrcA1.Exited nuevo EventHandler (ProcessExitedEvent), pero tampoco funcionó. Cualquier idea de cómo actualizar la barra de progreso en el formulario después de cada llamada a Processs. Start (). Aquí está el código de ejemplo: con Progressbar1.Step 25 private void InstallClick (remitente de objetos, System. EventArgs e) // Proceso de instalación de FPM prcA1 Process. Start (quotA1.exequot) //prcA1.Expected nuevo EventHandler (ProcessExitedEvent) // prcA1.EnableRaisingEvents true prcA1.WaitForExit () this. Activate () progressBar1.PerformStep () // Proceso de instalación del controlador prcB1 Process. Start (quotB1.exequot) // prcB1.Exited nuevo EventHandler (ProcessExitedEvent) // prcB1.EnableRaisingEvents true prcDriverB1. WaitForExit () progressBar1.PerformStep () // Proceso de instalación del controlador prcC1 Process. Start (quotC1.exequot) // prcC1.Exited nuevo EventHandler (ProcessExitedEvent) // prcC1.EnableRaisingEvents true prcC1.WaitForExit () progressBar1.PerformStep () // Proceso de instalación del controlador prcD1 Process. Start (quotD1.exequot) // prcD1.Exited nuevo EventHandler (ProcessExitedEvent) // prcD1.EnableRaisingEvents true prcD1.WaitForExit () progressBar1.PerformStep () // private void ProcessExitedEvent (object sender, System. EventArgs E) // // this. Activate () //progressBar1.PerformStep () // Martes, 21 de marzo de 2006 16:45


No comments:

Post a Comment