2008-11-06 19 views
41

He escrito un servicio de Windows que me permite ejecutar y detener aplicaciones de forma remota. Estas aplicaciones se ejecutan usando CreateProcess, y esto funciona para mí porque la mayoría de ellas solo realiza el procesamiento de back-end. Recientemente, necesito ejecutar aplicaciones que presenten GUI al usuario de inicio de sesión actual. ¿Cómo codigo en C++ para permitir que mi servicio ubique el escritorio actualmente activo y ejecute la GUI en él?¿Cómo puede un servicio de Windows ejecutar una aplicación GUI?

+0

¿A qué versión de Windows se dirige? Con Vista y 7 servicios de Windows no pueden tener componentes GUI. Mi investigación data de hace algunos años, pero está relacionada con la cuenta de administrador oculta/deshabilitada (sesión 0) en la que se ejecutan los servicios. Mi solución en ese momento era usar MSMQ para comunicarme entre el servicio y una aplicación GUI separada. – gooch

Respuesta

49

respuesta de Roger Lipscombe, para usar WTSEnumerateSessions para encontrar el escritorio correcto, entonces CreateProcessAsUser para iniciar la aplicación en ese escritorio (se le pasa el mango del escritorio como parte de la estructura STARTUPINFO) es correcta.

Sin embargo, yo recomendaría contra esto. En algunos entornos, como los servidores de Terminal Server con muchos usuarios activos, determinar qué escritorio es el "activo" no es fácil, y puede que ni siquiera sea posible.

Pero lo más importante es que si una aplicación aparece repentinamente en el escritorio de un usuario, esto puede ocurrir en un mal momento (ya sea porque el usuario simplemente no lo espera o porque está intentando iniciar la aplicación cuando la sesión aún no se ha iniciado del todo, en proceso de cierre, o lo que sea).

Un enfoque más convencional sería poner un acceso directo a una pequeña aplicación cliente para su servicio en el grupo de arranque global. Esta aplicación se lanzará junto con cada sesión de usuario, y se puede utilizar para iniciar otras aplicaciones (si así lo desea) sin ningún tipo de malabares de credenciales de usuario, sesiones y/o escritorios.

Además, este acceso directo se pueden mover/desactivado por los administradores como se desee, lo que hará que el despliegue de la aplicación mucho más fácil, ya que no se desvía de los estándares utilizados por otras aplicaciones de Windows ...

+0

Pero tendrá que llevar las credenciales del usuario, ¿verdad? – Prakash

6

WTSEnumerateSessions y CreateProcessAsUser.

0

Creo que siempre y cuando solo tenga un usuario conectado, se mostrará automáticamente en el escritorio de ese usuario.

De todos modos, tenga mucho cuidado al tener un servicio iniciar un exe.

Si el acceso de escritura a la carpeta con el exe no está restringido, cualquier usuario puede reemplazar ese exe con cualquier otro programa, que luego se ejecutará con derechos de sistema. Tomemos como ejemplo cmd.exe (disponible en todos los sistemas de Windows). La próxima vez que el servicio intente iniciar su exe, obtendrá un shell de comandos con derechos de sistema ...

0

Si inicia una GUI desde su servicio, se mostrará en el escritorio actualmente activo.

Pero solo si ajustó los permisos de servicio: debe permitirlo a interact with the desktop.

1

En Win2K, XP y Win2K3 el usuario de la consola ha iniciado sesión en la sesión 0, la misma sesión en la que viven los servicios. Si un servicio se configura como interactivo, podrá mostrar la interfaz de usuario en el escritorio del usuario.

Sin embargo, en Vista, ningún usuario puede iniciar sesión en la Sesión 0. Mostrar la interfaz de usuario de un servicio es un poco más complicado. Debe enumerar las sesiones activas usando la API WTSEnumerateSessions, buscar la sesión de la consola y crear el proceso como ese usuario. Por supuesto, también necesita un token o credenciales de usuario para poder hacer eso. Puede leer más detalles sobre este proceso here.

+0

¿De qué es este "el" que hablas? La única razón por la que estoy en la sesión 0 es porque era la primera sesión que no estaba en uso cuando me conecté ... – SamB

+0

En Win2K, XP y Win2K3, solo hay una sesión de consola, y siempre está en la Sesión 0. Todas otras sesiones son utilizadas por los usuarios TS. –

5

Varias personas sugirieron WTSEnumerateSessions y CreateProcessAsUser.Me pregunto por qué nadie sugirió WTSGetActiveConsoleSessionId, ya que dijo que solo desea apuntar a un usuario que ha iniciado sesión.

Sin embargo, varias personas tienen razón al sugerir CreateProcessAsUser. Si llama al viejo y simple CreateProcess de la manera que dijo, entonces la GUI de la aplicación se ejecutará con los privilegios de su servicio en lugar de los privilegios del usuario.

16

La respuesta breve es "No", ya que la apertura de un programa de GUI que se ejecuta en otro contexto de usuario es una vulnerabilidad de seguridad comúnmente conocida como Shatter Attack.

Eche un vistazo a este artículo de MSDN: Interactive Services. Ofrece algunas opciones para que un servicio interactúe con un usuario.

En resumen se tienen las siguientes opciones:

  • mostrar un cuadro de diálogo en la sesión del usuario mediante la función WTSSendMessage.

  • Cree una aplicación GUI oculta por separado y use la función CreateProcessAsUser para ejecutar la aplicación en el contexto del usuario interactivo. Diseñe la aplicación GUI para comunicarse con el servicio a través de algún método de comunicación entre procesos (IPC), por ejemplo, conductos con nombre. El servicio se comunica con la aplicación GUI para indicarle cuándo mostrar la GUI. La aplicación comunica los resultados de la interacción del usuario de vuelta al servicio para que el servicio pueda tomar la acción adecuada. Tenga en cuenta que IPC puede exponer sus interfaces de servicio a través de la red a menos que use una lista de control de acceso (ACL) apropiada.

    Si este servicio se ejecuta en un sistema multiusuario, agregue la aplicación a la siguiente clave para que se ejecute en cada sesión: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run. Si la aplicación utiliza canalizaciones con nombre para IPC, el servidor puede distinguir entre múltiples procesos de usuario al dar a cada canal un nombre único basado en la ID de la sesión.

0

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

Esto está tomado de: http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx

Cuestiones relacionadas