2012-04-19 9 views
6

Estoy comenzando una pequeña aplicación de consola desde mi aplicación web de IIS. El código se inicia desde dentro de un grupo de aplicación utilizando un código como éste,¿Qué diferencia tiene UseShellExecute?

Process process = new Process(); 
ProcessStartInfo processStartInfo = new ProcessStartInfo(); 

processStartInfo.CreateNoWindow = true; 
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

// .. 

process.Start(); 

que utiliza para obtener un error de forma intermitente,

Win32Exception exception has occured Message: No such interface supported 
ErrorCode: 80004005 NativeErrorCode: 80004002 

he demostrado que cuando esto sucedió la aplicación de consola no comenzaría a las todas.

que añade al código por encima de este,

processStartInfo.UseShellExecute = false; 

Y el problema ha desaparecido (hasta el momento, los dedos cruzados). Entiendo que al hacer este cambio no es necesario ejecutar un contexto de escritorio válido, pero qué significa exactamente eso. Si eso significa que no podemos ejecutar el código anterior si no hay un escritorio (que se aplica a un grupo de aplicaciones IIS que se ejecuta con un usuario del sistema), ¿por qué solía ejecutarse en ocasiones en el pasado en lugar de fallar todo el tiempo?

¿Alguien tiene alguna idea de por qué esto marcaría la diferencia? ¿Qué significa que no admite interfaz en este contexto?

ACTUALIZACIÓN:

he tenido en cuenta todo lo que la gente ha dicho, y hecho más yo misma investigación. Entonces, para resumir si tiene UseShellExecute = true (que es el valor predeterminado), entonces se llamará a ShellExecuteEX en shell32.dll para ejecutar el proceso. Esto se hará realidad (copiado del System.dll usando ILSpy),

public bool ShellExecuteOnSTAThread() 
{ 
    if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) 
    { 
     ThreadStart start = new ThreadStart(this.ShellExecuteFunction); 
     Thread thread = new Thread(start); 
     thread.SetApartmentState(ApartmentState.STA); 
     thread.Start(); 
     thread.Join(); 
    } 
    else 
    { 
     this.ShellExecuteFunction(); 
    } 
    return this._succeeded; 
} 

Si tiene UseShellExecute = false entonces se llamará a CreateProcess en kernel32.dll para iniciar el proceso.

Me preguntaba si hay un problema con el hecho de que el código ShellExecuteOnSTATread anterior está creando un nuevo hilo? ¿Podría el grupo de aplicaciones llegar a algún límite en el subproceso que indirectamente podría causar una excepción Win32Exception?

+0

He visto este modo de falla específico mencionado varias veces en los últimos meses. Nada cerca de una explicación, pero usar UseShellExecute = false lo arreglará con cierta certeza. –

+0

Gracias. ¿Dónde más lo has visto? Realmente no puedo encontrarlo en ningún lado? Lo siento si hago una pregunta que no puede responder, pero me gustaría saber si puede encontrarla. – peter

+1

Esto no responde a lo que Hans está tratando, pero esta pregunta SO tiene algunos detalles interesantes: http://stackoverflow.com/questions/5255086/when-do-we-need-to-set-useshellexecute-to-true –

Respuesta

7

Este error puede ocurrir cuando ciertos objetos COM no están registrados, aunque es un misterio para mí por qué es intermitente.

Para ser justos, engendrar un ejecutable local desde IIS es algo bastante raro de hacer y en realidad puede causar un problema de seguridad, o al menos causar un problema con IIS si el comando falla por algún motivo y no lo hace t devolver el control al sistema.

En realidad, la mejor práctica para algo así es registrar la acción que necesita suceda dentro del registro, base de datos o algún tipo de archivo de configuración y hacer que su aplicación local se ejecute como una tarea programada o un servicio de Windows.

Como referencia, UseShellExec indica si el Kernel debe iniciar el exe directamente o si debe solicitarle al Explorer que lance el archivo.

Es posible que aparezca este problema cuando no haya nadie conectado, por lo que no es necesario cargar el shell para ejecutar el archivo ejecutable.

Sin embargo, lo que está intentando hacer actualmente es algo malo en la producción: no se puede garantizar el estado de IIS cuando intenta ejecutar este exe y con razón, IIS no es un Shell.

+0

Para calificar el problema de seguridad, IIS normalmente se ejecuta con privilegios altos y el inicio de un proceso de la manera que está intentando lo lanzará con el mismo conjunto de privilegios. En mi humilde opinión esto rara vez es algo bueno. –

+1

OK, gracias. No me preocupa la seguridad, no tengo tiempo para explicar la historia completa sobre eso. Estoy de acuerdo, usted dice que podríamos obtener el problema cuando no hay nadie conectado al servidor. Suena correcto, pero no parece ser el caso. Debe relacionarse con algún otro problema que causa 'cargar el caparazón'. – peter

+0

Dejando a un lado la seguridad, sigue siendo una cuestión de tener un estado válido en el servidor. ¿Qué sucede si algo detiene el exe y el proceso de trabajo de IIS se reinicia o gira debido a un tiempo de espera de actividad? Supongo que saber lo que este ejecutor pretende hacer es ayudar; incluso si solo puedes proporcionar la vista de una milla de altura. –