2010-12-23 20 views
7

He creado un servicio de Windows con temporizador y en evento de disparo de timer.Elapsed Estoy creando un proceso (System.Diagnostics.Process.Start(exe path)) con un intervalo de 5 segundos. Pero este proceso no se crea al disparar un evento.¿Cómo puede un servicio de Windows iniciar un proceso cuando se produce un evento de temporizador?

¿Hay alguna otra forma de hacerlo?

Gracias de antemano.

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{  

    Process pr = new Process(); 
    pr.StartInfo.FileName = @"C:\Program Files\Messenger\msmsgs.exe"; 
    pr.StartInfo.WindowStyle = ProcessWindowStyle.Normal; 
    pr.StartInfo.CreateNoWindow = false; 
    pr.Start(); 
} 
+0

¿O se crea y luego sale inmediatamente? Si puede pegar el código aquí, sería útil –

+3

** Los Servicios de Windows no están diseñados para ejecutar aplicaciones interactivas. ** Usted * puede * ejecutar un proceso, pero abrir una nueva ventana es una propuesta arriesgada. Sin mencionar todos los problemas de seguridad con los que se encontrará al tratar de hacer esto. Lo más probable es que necesite reconsiderar su diseño y usar algo que no sea un servicio de Windows, * especialmente * si sus usuarios objetivo ejecutan Windows Vista o más adelante teniendo en cuenta su modelo de seguridad más estricto para los servicios. –

+0

Además, vea posible duplicado aquí: http://stackoverflow.com/questions/677874/starting-a-process-with-credentials-from-a-windows-service (explicando cómo puede elevar el servicio para que se ejecute con diferentes credenciales) y/o en modo interactivo (nota: esto es [no compatible] (http://www.microsoft.com/whdc/system/sysinternals/Session0Changes.mspx) en Vista o posterior)). –

Respuesta

19

Está agregando descripciones del problema en los comentarios a medida que avanza que le habría sido útil conocer desde el principio. La razón por la que puede ver que el proceso ha comenzado, pero no se abre ninguna ventana, se debe a los cambios en el modelo de seguridad que se realizaron a los Servicios de Windows en Windows Vista y posteriores. Aún no lo has mencionado específicamente, pero tengo una fuerte sospecha de que estás tratando de ejecutar esto en uno de esos sistemas operativos. El verdadero problema no es comenzar un proceso, sino mostrar una IU.

Lo que estamos tratando de lograr que se llama un "Interactive Service", que es uno que se le permite interactuar directamente con el usuario y el escritorio (es decir, mostrar una ventana o cuadro de diálogo).
Si está usando Windows XP (y su servicio solo tendrá tiene que ejecutarse bajo Windows XP), puede seguir las instrucciones en ese artículo para permitir que su servicio se ejecute en modo interactivo, lo que le permitirá visualizar la ventana de la aplicación Adobe Acrobat como espera. Sin embargo, como que la documentación también indica, esta característica no funciona bajo Windows Vista y más tarde:

importantes   Los servicios no pueden interactuar directamente con un usuario como de Windows Vista. Por lo tanto, las técnicas mencionadas en la sección titulada Usar un servicio interactivo no se deben utilizar en el nuevo código.

Más específicamente, en esas versiones, se realizaron cambios en cómo se ejecutan los servicios y las aplicaciones. Los servicios ahora están aislados por el sistema en la Sesión 0, mientras que las aplicaciones se ejecutan en otras sesiones. Esto tiene como objetivo aislar los servicios de los ataques que se originan en el código de la aplicación. Por lo tanto, ninguna UI mostrada por un servicio será visible para ningún usuario en el sistema, incluido un simple cuadro de mensaje. Puede leer el libro blanco que explica estos cambios en más detalle here. Si usted es una persona más visual, consulte el siguiente diagrama que ilustra el nuevo modelo, prestando especial atención a las líneas divisorias:

          Windows process isolation model under Windows Vista/7

El resultado es que si usted está apuntando a los versiones, o podría necesitar enfocarse en esas versiones, no puede usar esta laguna. Digo "escapatoria" porque la línea de fondo, como mencioné en un comentario, es que los Servicios de Windows no están destinados a ser interactivos. Lo que intenta hacer aquí va en contra del propósito y el diseño de un servicio. No fue recomendado antes, y ahora no funciona en absoluto. Si necesita esta funcionalidad en particular, debe crear un tipo diferente de aplicación. Tanto Windows Forms como WPF están destinados a aplicaciones en modo usuario, y ambos pueden iniciar procesos y abrir ventanas nuevas según sea necesario. Recomiendo encarecidamente que se convierta en este estilo de aplicación en su lugar.

+0

¿Hay algún método para implementar GlobalKeyHook a través del servicio de Windows? y también el servicio puede mirar los eventos de pulsación de tecla 'SetWindowsHookEx'? – Elshan

+0

@Jimmer No. [Global Keyboard Hook from windows service] (http://stackoverflow.com/q/5815424) –

0

Dado que no obtendrá un proceso para mostrar la IU del servicio, le recomiendo que ejecute el proceso de ayuda cuando el usuario inicie sesión e inicie el proceso desde allí.

+0

No lo hago. Al menos no necesariamente ... ¿Por qué crear un servicio * y * un proceso de ayuda? Si cree que necesita crear un proceso de ayuda que se inicie automáticamente al iniciar sesión (blech), debe volver a evaluar seriamente si necesita un servicio en primer lugar. Solo porque * puedas * hacer algo no significa que te lo recomienden. –

+0

Sí, tienes razón en esto. Sin embargo, si necesita algo que se ejecutará SIEMPRE e informará al usuario A VECES, esta arquitectura es bastante buena. –

0

Me doy cuenta de que llego un poco tarde a esta fiesta. Pero dado que surgió esta pregunta en mi búsqueda de una solución, proporcionaré una respuesta a la pregunta del OP.

Puede iniciar un programa desde un servicio utilizando CreateProcessAsUser, utilizando el token del usuario que ha iniciado sesión. MSDN proporciona una buena aplicación de ejemplo que lo demuestra; busque CSCreateProcessAsUserFromService: https://code.msdn.microsoft.com/windowsapps/CSCreateProcessAsUserFromSe-b682134e#content

Lo intenté, y funciona. Puedo crear un nuevo proceso para mi aplicación .NET existente desde un servicio, y funciona muy bien. Establecí las propiedades de inicio de sesión del servicio en la cuenta del sistema local, pero dejé sin marcar la opción "Permitir que el servicio interactúe con el escritorio". Mi aplicación se crea cuando expira el temporizador y funciona igual que cuando se inicia normalmente, incluida la presentación de la GUI y la interacción del usuario.

Si esto es algo indebido o indeseable es otra discusión. Pero de hecho es posible, y realmente no es tan difícil.

0

Existe un tipo de solución alternativa, pero le aconsejo que solo haga esto si ESTÁ SEGURO DE ACEPTAR EL PROBLEMA DE SEGURIDAD.

Esta podría ser la respuesta a su problema: CreateProcessAsUser.

El ejemplo muestra cómo crear/iniciar un proceso de forma interactiva en la sesión del usuario conectado desde una aplicación de servicio escrita en C# .Net.

Cuestiones relacionadas