Pregunta

Estoy corriendo un proceso desde el interior de un servicio de Windows utilizando

ProcessStartInfo processStartInfo = new ....
Process.Start(processStartInfo);

El problema es, si me quedo servicio bajo cuenta del sistema local, se ejecuta bien, pero no muestra la ventana de los programas. He tratado de poner las credenciales de usuario en las propiedades del servicio, pero entonces 'Permitir a los servicios interactuar con el escritorio' casilla de verificación se convierte en desactivar.

Es realmente necesario para ejecutar la aplicación llamando para darle servicio, y realmente necesita para ver la ventana de la aplicación.

Ayuda conmigo por favor.

UPD. que se tire el programa para el escritorio - Bueno, se utiliza la versión de Process.Start lo que toma nombre de usuario, contraseña y dominio sobrecargado. Pero ahora que se inicia la aplicación bajo uno credenciales sino que muestra que en el escritorio de un usuario diferente. ¿Por qué?

UPD2: Tengo una idea! Puedo usar psexec.exe de Sysinternals Suite. Pero el problema es que tengo que empezar esa cosa en silencio "como administrador". Y no sé cómo. Es decir, incluso si ya estás han derechos de administrador, a veces hay que decir de forma manual "Ejecutar como administrador", confirman UAC y sólo después de que usted está listo para ir. No sé cómo funciona silenciosamente sin traer algo que UAC ....

UPD3: Estimado Señor. Tengo esa cosa! Por último.

Ok. Al principio, el problema era de hecho en la sesión 0 cosa aislada. Así que necesitaba para construir una aplicación media que se puede iniciar desde el servicio y luego, esa aplicación, a su vez supone que debe comenzar mi solicitud a través de RPC y llevarlo a un ordenador de sobremesa. En lugar de construir aplicación de capa media, decidí utilizar la herramienta psexec (todos modos funciona exactamente de la manera que necesito - a través de RPC). Y cuando traté de utilizar esa herramienta bajo LOCAL sistema de cuenta que no funciona por alguna razón. Y entonces me di cuenta - la razón es maldita diálogo emergente EULA miembros determinen en cada PsTool, y era imposible hacer clic en el botón para diálogo de confirmación en la cuenta del sistema local. Así que la solución es crear una clave en el registro HKU.DEFAULT \ Software \ Sysinternals \ PsExec con valor DWORD EulaAccepted = 1

Hurra, ahora funciona! ¡PERO! Ahora tengo que llevar el programa a la pantalla del usuario que ha iniciado sesión. Para ello voy a necesitar el id de sesión!

Entonces la pregunta es: ¿Cómo obtener actualmente registra identificador de sesión de usuario? Y lo que ocurre si no hay nadie todavía conectado? ¿Qué identificador de sesión que sería?

UPD4: Eso es todo! Tengo que uno!

[DllImport ( "Kernel32.dll", EntryPoint = "WTSGetActiveConsoleSessionID")] pública extern int estática WTSGetActiveConsoleSessionID ();

Gracias chicos!

¿Fue útil?

Solución

Una solución sería tener un tercer acto proceso como intermediario, y decirle que iniciar aplicaciones a través de RPC / canalizaciones con nombre.

Procesos:

  • Servicio de Windows
  • aplicación Intermediario
  • La aplicación que desea ejecutar

La cuña crea un punto final de la comunicación (tubería con nombre, WCF punto final) y escuchas en él. Cuando se recibe un mensaje de seguir adelante, se lanza la aplicación que desea ejecutar.

A continuación, cuando el servicio de Windows quiere poner en marcha una aplicación, que encuentra y abre el punto final (tubería con nombre, WCF punto final), y envía el mensaje a lanzar la aplicación. A continuación, la aplicación intermediario se hace cargo de la empresa proceso de puesta en marcha, y no tiene ninguna de las limitaciones que el servicio Windows tiene.

Hacer este proceso intermediario comienza con el inicio de sesión, y ya está bueno para ir.

Esto es similar a cómo el trabajo del agente de prueba / controlador de Microsoft cuando se necesita para ejecutar las pruebas que interactúan con el escritorio.

Otros consejos

Se puede obtener la sesión de consola activa Identificación del uso de WTSGetActiveConsoleSessionID (de la API de servicios de terminal). Sólo se puede utilizar para WinXP / Win2K3 o superior, pero que debe estar bien, como se puede codificar 0 para el id de sesión en Win2K o antes. Aquí está la firma PInvoke para ello:

[DllImport("Kernel32.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.U4)]
public static extern int WTSGetActiveConsoleSessionId ( );

Por lo que el lanzamiento de un proceso en la sesión del usuario, puede hacer referencia a la respuesta que di aquí . Básicamente, consiste en cuatro callling API; WTSGEtConsoleSessionId, WTSQueryUserToken, DuplicateTokenEx, entonces CreateProcessAsUser, y funcionará en cualquier máquina que ejecuta WinXP / Win2K3 o superior.

Esto se puede hacer sin un proceso intermedio, pero requiere más de 500 líneas de código para hacer. Básicamente, usted quiere poner en marcha su segundo proceso como el actual usuario registrado. Para Vista / 7, el usuario tendrá su propio proceso Winlogon, mientras que para XP, tendrán un proceso de explorador. Es necesario para obtener el identificador primario, bloque de entorno, los atributos de seguridad, y atributos de seguridad hilo de ese proceso que se ejecuta a continuación, llamar a la CreateProcessAsUser función de la API de Windows con toda esa información, asegurándose de seleccionar la estación de ventana correcta, así (por lo general "WinSta0 \ Default "). Todo esto es factible, pero es posible que tenga un mejor momento con la otra sugerencia de un segundo proceso e IPC.

Si usted está tratando esto en nada más nuevo que Windows XP esto no va a funcionar. Esto se debe a una nueva característica introducida en Vista / Windows 7 llamada Sesión 0 aislamiento. http://msdn.microsoft.com/en-us/library/bb756986. aspx Usted no será capaz de obtener una aplicación lanzada por un servicio a aparecer en el escritorio de los usuarios.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top