2012-02-02 8 views
8

que tienen un servicio de Windows que contiene este código:¿Por qué Process.WaitForExit arroja una excepción de "no proceso" incluso cuando existe un proceso?

public static void ExtractTextInner(string source, string destination) 
    { 
     ProcessStartInfo startInfo = new ProcessStartInfo(); 
     startInfo.FileName = EXTRACTOR_EXE_FILEPATH 
     startInfo.Arguments = "\"" + source + "\" \"" + destination + "\""; 
     startInfo.CreateNoWindow = true; 
     startInfo.WindowStyle = ProcessWindowStyle.Hidden; 

     Process process = new Process(); 
     process.StartInfo = startInfo; 

     process.Start(); 
     process.WaitForExit(); 
     int exitCode = process.ExitCode; 
     process.Close(); 
     if (exitCode != 0) 
     { 
      switch (exitCode) 
      { 
       case 1: 
       throw new ApplicationException("IFilter Extraction Failed"); 
       default: 
       throw new ApplicationException("Unknown Exit Code:" + exitCode.ToString()); 
      } 
     } 
    } 

El propósito de este código se ejecuta un extracto IFilter en un documento, usamos un proceso separado debido a que algunos IFilters son notoriamente escamosa.

Ahora este código funciona perfectamente bien en los cuadros de Windows 7 y Server 2008 R2, pero en un Windows Server 2003 el WaitForExit lanza inmediatamente una excepción "No hay proceso asociado con este objeto de proceso". El proceso existe y completa su tarea sin problemas.

¿Alguien ha visto esto? ¿Alguien puede arrojar alguna luz sobre por qué WaitForExit daría este error?

Información adicional

Si coloco el código en una aplicación de consola y ejecutarlo trabaja muy bien en el cuadro de Windws Server 2003, así, por lo que parece ser un problema específico de ejecutar este en un servicio en un cuadro de Windows Server 2003.

+0

Eso es muy difícil de explicar con este código. Tinker con la configuración del servicio. Asegúrese de que la opción "interactuar con el escritorio" esté desactivada. Publique todo lo que encuentre en el registro de eventos de la aplicación. –

+1

El error ocurre cuando no se obtiene un MANIJA para el proceso (por lo tanto, no puedo esperar). Asegúrese de especificar UseShellExecute = false, para evitar reutilizar un proceso. También puede describir la bitness 32 vs 64 del servicio vs. el ejecutable? Por último, pruebe Process Monitor y vea lo que está sucediendo. – Ben

+0

@Hans: no aparece nada en ninguno de los registros de eventos (al menos nada que mi código no incluya deliberadamente).No estoy seguro de dónde encontrar la opción "interactuar con el escritorio"? – AnthonyWJones

Respuesta

13

Al iniciar procesos, con la clase System.Diagnostics.Process, el sistema puede usar la función CreateProcess o ShellExecuteEx Win32. Al usar CreateProcess, solo se pueden iniciar los archivos ejecutables. Al usar ShellExecuteEx, cualquier archivo que pueda iniciarse con el comando "Inicio-> Ejecutar" del shell.

Sin embargo, estas son formas completamente diferentes de iniciar procesos. ShellExecuteEx implica el shell y puede, por ejemplo, reutilizar una instancia existente de Word o Excel para abrir un documento, utilizando la información almacenada en la clave de registro HKCR\<progid>\shell\<verb>. Esto puede implicar, por ejemplo, usar DDE para buscar y luego activar una instancia existente de Excel.

Ver documentación sobre ShellExecuteEx 's SHELLEXECUTEINFO:

Tenga en cuenta que ShellExecuteEx puede o no puede devolver un hProcess dependiendo de si se inicia un nuevo proceso. Este es el comportamiento que estás viendo.

CreateProcess es una función de nivel inferior y crea un proceso directamente, y simplemente pasa los argumentos equivalentes. Siempre devuelve un identificador de proceso.

Nota: Ya que parece estar empezando un archivo ejecutable, que es un poco sorprendente que ningún hProcess es devuelto por ShellExecuteEx. Sin embargo, si desea asegurarse de obtener un identificador de proceso, usar UseShellExecute = false es lo correcto.

Cuestiones relacionadas