Pregunta

Escribí un pequeño servicio (Win32 simple) y me gustaría saber si es posible ejecutar varias instancias del mismo cuando varios usuarios inician sesión.

Básicamente, digamos que tenemos UsuarioA y UsuarioB, para UsuarioA, el servicio iniciará sesión como "dominio\UsuarioA" y para UsuarioB, el servicio iniciará sesión como "dominio\UsuarioB"; esto es del mismo ejecutable, por supuesto.Puedo cambiar el inicio de sesión dinámicamente usando la función ChangeServiceConfig(), pero parece que lo cambia en todo el sistema, mientras que me gustaría que cada usuario tenga su propia copia del servicio ejecutándose solo para él.

Gracias de antemano por cualquier sugerencia.

¿Fue útil?

Solución

Los servicios Win32 están diseñados para abarcar todo el sistema y comenzar a ejecutarse antes de que cualquier usuario inicie sesión.Si desea que algo se ejecute por usuario, probablemente sea mejor diseñarlo como una aplicación normal y ejecutarlo desde el grupo de inicio del usuario.

Otros consejos

¿Es posible que el servicio cree procesos secundarios que luego adopten las credenciales del usuario (o comiencen con ellas)?De esta manera, todavía estará limitado a una única instancia del servicio, pero de todos modos podrá realizar sus trabajos por usuario.IIRC, el servicio Programador de tareas de Windows hace esto.

El concepto general de un servicio es que se inicia incluso antes de que cualquier usuario inicie sesión.Entonces, incluso si esto fuera posible, no podría elegir entre el usuario A y el usuario B cuando se inicie el servicio porque ninguno de ellos ha iniciado sesión todavía.


Una posible dirección sería que el servicio se ejecute como SISTEMA y cada pocos minutos verifique si hay un usuario conectado, si lo hay, suplante a ese usuario y haga estas cosas.

Sí, eso suena parecido (estoy respondiendo al comentario de Greg, pero los comentarios son demasiado breves para caber en mi respuesta).

No conozco la lista de usuarios de antemano, pero hay una aplicación de control GUI que se usaría para ingresar pares de nombre de usuario/contraseña para cada usuario.Entonces, el usuario A iniciaría sesión, ejecutaría la aplicación, ingresaría sus credenciales y el servicio las usaría.Al mismo tiempo (después de que el usuario A haya cerrado sesión, pero el servicio aún se está ejecutando con las credenciales del usuario A), el usuario B inicia sesión, usa la aplicación y otra copia del servicio comienza a ejecutarse cuando el usuario B inició sesión.Por lo tanto, al mismo tiempo se ejecutan los servicios de usuarioA y usuarioB.

¿Es eso posible?

Probablemente esté buscando hacerse pasar por los usuarios.Vea algunas referencias que encontré con una búsqueda rápida en Google aquí:

Parece como si en realidad tuviera dos requisitos diferentes y contradictorios en cuanto a tiempo e identidad.

  1. Ejecutar como cada usuario que ha iniciado sesión
  2. Se ejecuta automáticamente incluso si ningún usuario ha iniciado sesión.

No hay forma de hacer esto de manera trivial; en su lugar, considere envolver su programa en un servicio;el programa se ejecutará normalmente al inicio para cada usuario (ya sea a través de la carpeta de inicio o del programador de tareas), y además cree un servicio para ejecutar su aplicación como usuario del sistema (o cualquier otro usuario que defina).
Dado que también necesita (lo menciona en los comentarios) que la aplicación siga ejecutándose como usuario final incluso después de cerrar sesión, puede hacer que el servicio administre este proceso por usted.

SIN EMBARGO, esta podría no ser la mejor idea, ya que el usuario todavía está efectivamente conectado.Esto puede tener numerosos efectos secundarios, incluida la seguridad, el rendimiento (demasiados usuarios inician sesión a la vez...), etc.

Puede crear una aplicación de servicio y una aplicación que no sea de servicio (normal) y hacer que se comuniquen a través de IPC (archivo mapeado, tuberías, MailSolts...Tu dilo).

De esta manera resuelves todos los problemas.

NOTA:La misma aplicación puede comportarse de manera diferente: cuando se inicia como un proceso y cuando la inicia un usuario, pero al final es lo mismo, todavía tienes 2 aplicaciones (no importa si solo tienes un ejecutable).

Es posible ejecutar con diferentes cuentas.De hecho, esto es común.Consulte svchost.exe, que implementa una serie de servicios del sistema operativo.

Simplemente no entiendo cómo se determina qué cuentas.En una gran empresa, muchas PC están configuradas para que sus más de 100.000 empleados puedan utilizarlas.No desea ejecutar su servicio como los usuarios que iniciaron sesión, ni puede ejecutarlo para los 100.000 usuarios.Entonces, ¿para qué cuentas tengo que preguntar?

Un proceso de Windows sólo puede ejecutarse con los privilegios de un único usuario a la vez.Esto se aplica a los servicios y otros procesos.Con suficientes privilegios es posible "alternar" entre diferentes usuarios mediante la suplantación.El patrón más común para lo que intenta hacer es tener una instancia de un servicio privilegiado que se registre para eventos de inicio/cierre de sesión y cree procesos secundarios en consecuencia, cada uno de ellos haciéndose pasar por el usuario que inició sesión.El patrón también simplificará la interfaz de usuario ya que cada proceso se ejecuta en el escritorio de cada usuario por separado, como si fuera una aplicación normal.

Si mantiene el código del servicio privilegiado lo más simple posible, este patrón tiene el beneficio adicional de que está minimizando la superficie de ataque de su código.Si un usuario encuentra un problema de seguridad en el lado de "ejecución como usuario" de su servicio, no es un problema, mientras que los problemas de seguridad en los servicios privilegiados podrían provocar una escalada de privilegios.De hecho, antes de Vista, los servicios privilegiados que implementaban un bucle de procesamiento de mensajes de Windows eran vulnerables a un tipo de ataque llamado Ataques destrozados, lo cual debe tener en cuenta dado lo que está intentando hacer.

Quiere que esto se ejecute todo el tiempo, por eso quiere un servicio.

Quiere algo que rastree a cada usuario, por lo que quiere una aplicación que se ejecute en la sesión del usuario y se comunique con el servicio (mediante canalizaciones con nombre o DCOM o lo que se ajuste a sus requisitos).

No necesita varias instancias de su servicio.Según la descripción de su problema, parece que lo que necesita es un servicio que pueda hacerse pasar por usuarios y ejecutar trabajos en su nombre.

Puede hacerlo implementando un objeto COM alojado en un servicio.Su aplicación cliente (que ejecuta el usuario final) llamará a CoCreateInstanceEx en su CLSID.Esto provocaría que se creara una nueva instancia de su objeto COM en su servicio.Luego, la aplicación puede usar un método en una de sus interfaces para pasar las credenciales de usuario recopiladas al objeto COM (aunque sería cauteloso al recopilar credenciales y, en cambio, vería si puedo pasar el token de usuario).El objeto COM que se ejecuta en el contexto del servicio puede luego llamar a LogonUser() para iniciar sesión en el usuario y hacerse pasar por él, de modo que pueda hacer lo que sea en su nombre (como buscar la carpeta de datos de aplicación local del usuario :-)).Otras respuestas tienen buenos enlaces para hacerse pasar por usuarios utilizando credenciales o tokens.

Si se siente cómodo con COM, le sugiero que cree sus objetos como multiproceso (que viven en el MTA), para que COM no serialice su ejecución.De lo contrario, el modelo predeterminado de un solo subproceso sería suficiente para usted.

El asistente ATL de Visual Studio puede generar el esqueleto de un objeto COM que se encuentra en un servicio.También puede leer sobre la implementación del servicio de Windows con ATL aquí: http://msdn.microsoft.com/en-us/library/74y2334x(VS.80).aspx

Si no conoce COM en absoluto, puede utilizar otros canales de comunicación para pasar las credenciales a su servicio.

En cualquier caso, una vez que su servicio obtenga las credenciales, todo el trabajo en nombre del usuario deberá ejecutarse en un hilo en segundo plano, para no bloquear la aplicación que se ejecuta como el usuario.

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