PDA

Ver la Versión Completa : Restringir programas de windows


desve
10-10-2005, 20:26:08
Hola, quisiera saber si hay alguna forma desde delphi que mientras una aplicacion esté corriendo no permita usar otros programas o dicho de otra manera...

Que permita correr solo una lista de programas predefinida, esto con el fin de tener un sistema que controle un laboratorio de computo y que deban de loggearse cuando vayan a utilizar la maquina, pero como se debe de cotejar si no existen castigos en otro lugar deberia de utilizar conexiones y la aplicacion de la que hablo.


Por lo que no se si haya alguna manera de restringir los demas programas, o bien
autorizarlos, con algun componente, alguna libreria.


Gracias, agradezco de antemano su ayuda.

roman
10-10-2005, 20:46:29
Para esto yo lo que haría es reemplazar el shell de windows (explorer.exe) por una aplicación propia que funcione como lanzadera y sólo presente los programas que se deseen. Además poner alguna política para evitar que puedan ejecutar una aplicación con el administrador de tareas.

// Saludos

desve
10-10-2005, 21:02:11
Bueno podria ser, pero al parecer no me supe explicar, ya que necesito que esta aplicacion corra como residente para que cuando se loggeen les de acceso a todos los programas, y al cerrar la sesion en el programa les vuelva a bloquear la computadora, para esperar que de nuevo introduzcan otro usuario y otro password para poder iniciar sesion y asi tener acceso a los recursos del sistema.

roman
10-10-2005, 21:10:31
para que cuando se loggeen les de acceso a todos los programas, y al cerrar la sesion en el programa les vuelva a bloquear la computadora, para esperar que de nuevo introduzcan otro usuario y otro password para poder iniciar sesion y asi tener acceso a los recursos del sistema.

¿Te das cuenta de que lo que describes es lo mismo que de por sí hace Windows?

1. Presenta un cuadro de login para iniciar sesión
2. El usuario pone sus datos
3. Si los datos son válidos el sistema se inicia y tiene acceso a las aplicaciones
4. El usuario termina sesión
5. Se presenta nuevamente el cuadro de login

Así que, ¿qué es exactamente lo que quieres?

// Saludos

desve
10-10-2005, 21:27:09
Exacto es practicamente lo que utiliza el login de windows, pero existen unas cuantas cosas que necesito hacer con esa informacion.

1. Se debe de cotejar en una BD remota que el usuario exista, no tenga castigos o adeudos.

2. se insertara en una BD el numero de maquina, la hora y el usuario que la utiliza, asi como cuando termina. (EL PUNTO IMPORTANTE ES ESTE, LLEVAR UN CONTROL).

3. Resultaria dificil utilizar el cuadro de login de windows, ya que las computadoras de laboratorio de una universidad despues de un tiempo de uso se vuelven lentas, y existiria demasiado tiempo muerto en apagar y prender.

Como se necesita acceder a una BD externa necesitaria tener corriendo aplicaciones de conexiones cliente a BD, y eso no creo que sea posible correr si no se ha iniciado la sesion.

Ahora que estuve platicando con algunas personas, y me comentaban la posibilidad de tener una aplicacion que corra maximizada y desactive el boton de inicio de windows, el alt+tab, y el ejecutar.

Posiblemente esta sea una opcion mas razonable de implementar, o no se que pienses...

roman
10-10-2005, 21:43:53
Por lo que mencionas en el punto 3 no sé si lo que te voy a decir te funcione. Yo hago algo parecido para una sala de cómputo en donde debe registrarse la hora de entrada y de salida así como otros datos pertinentes para cada usuario.

Básicamente lo que hago es:

1. Configurar la pc para iniciar automáticamente con un usuario determinado, digamos, 'estudiante'. Este es un usuario de Windows, no de mi sistema.

2. Para este usuario reemplazo el shell de Windows. Para ello, si no mla recuerdo, agregas en el registro de Windows, en la clave

HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon

la entrada Shell que apunte a tu propia aplicación.

Nota que es Windows NT y no Windows aunque el S.O sea Windows XP o 2000
También nota que esta entrada existe en

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon

pero esto cambiaría el shell para cualquier usuario y te sería más difícil acceder para otros menesteres. Así, yo puedo entrar como administrador y el shell sigue siendo el explorer

3. La aplicación que sustituye al shell, digamos, controlador.exe, lo primero que hace es presentar su propio cuadro de login y ella misma hace la autenticación ya en el sistema de control y no en Windows. De hecho, controlador.exe correrá después del login de Windows, de ahí que configure la máquina para que por defecto entre como usuario 'estudiante'

Como no hay shell, el usuario no puede hacer nada aparte de interactuar con el cuadro de login (hay que deshabilitar la ejecución de programas del administrador de tareas, lo cual puedes hacer con gpedit.msc o directamente en el registro de Windows)

De ese cuadro de login sólo hay dos formas de salir:

a) Oprimiendo un botón que manda cerrar la sesión de Windows, con lo que se sigue sin tener acceso a la pc

b) Proporcionando los datos correctos.

4. controlador.exe verifica contra la base de datos la validez de los datos. Si éstos son correctos entonces, y sólo entonces, manda llamar a explorer.exe

5. En mi caso particular, controlador.exe continúa presentando ya la ventna principal que no es si no una barra similar a la barra de tareas de Windows, que coloco en la parte superior de la pantalla y donde muestro el nombre del usuario y tiene botones o menús para las distintas opciones particulares del sistema. Entre éstas, la de terminar la sesión, con lo cual grabo la hora de salida y demás menesteres apropiados.

// Saludos

desve
10-10-2005, 22:29:47
Gracias, parece ser la solucion, intentare implementarlo y en caso de que tenga algun problema te consulto.

Como un punto mas, y solo como cultura general como es que logras una barra en la parte superior que componente usas, lo haces residente,?,,, si me orientaras en eso, seria algo mas que te agradeceria, gracias.

otra cosa?,, una vez cerrada la sesion, keda solo funcionando el controlador.exe... y en caso de que inicie sesion, windows volvera a cargar los programas que necesita, o ya los tendra en memoria??

roman
10-10-2005, 22:53:08
No sé qué entiendes por aplicación residente. Ya no estamos en la era del DOS :p.

Controlador.exe no es más que una aplicación como cualquier otra cuyo formulario principal tiene forma de barra y la coloco en la parte superior. La parte "difícil" es lograr que el sistema reconozca al formulario como una barra para que ventanas de otras aplicaciones no se monten sobre ella. En esto también te puedo ayudar pero lo mejor es que primero programes lo fundamental.

Detalles a tener en cuenta:

Lógicamente querrás impedir que cierren tu aplicación, para lo cual usas el evento OnCloseQuery del formulario. Sin embargo esto impedirá que se pueda cerrar la sesión de Windows pues tu aplicación no lo permitirá.

Para remediar lo anterior debes crear manejadores para los mensajes WM_QUERYENDSESSION y WM_ENDSESSION usando una variable booleana que le indique al evento OnCloseQuery si se está cerrando la sesión de Windows.

Yo lo tengo así:


(* Al recibir la petición para cerrar la sesión de Windows debemos ajustar *)
(* la bandera WinSessionEnding a true para permitir al evento CloseQuery *)
(* cerrar la ventana. *)
procedure TMainForm.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
WinSessionEnding := true;
inherited;
end;

procedure TMainForm.WMEndSession(var Msg: TWMEndSession);
begin
(* Terminar sólo si se confirma el cierre de sesión *)
WinSessionEnding := Msg.EndSession;
inherited;
end;

{
En este evento impedimos que el usuario pueda cerrar la aplicación
excepto cuando termine la sesión de Windows.
}
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if WinSessionEnding then
begin
(* Marcar la sesión en MySql como cerrada *)
DmData.ZQuery.SQL.Text := Format(sCloseSession, [SesionId]);
DmData.ZQuery.ExecSQL;
end
else
CanClose := false;
end;


Hay otro problema concerniente a cómo Windows envía estos mensajes:

Anteriormente el proceso era el siguiente:

Cuando el usuario pide cerrar la sesión, el sistema manda el mensaje WM_QUERYENDSESSION a todas las aplicaciones abiertas para preguntarles si aceptan el final de la sesión.

Si todas las aplicaciones aceptan, entonces el sistema manda el mensaje WM_ENDSESSION nuevamente a todas las aplicaciones para que cada una realice las rutinas necesarias antes de cerrarse (p. ej. grabar la hora de salida en tu caso)

Si una aplicación no acepta, el sistema deja de enviar el mensaje WM_QUERYENDSESSION y ya no manda el mensaje WM_ENDSESSION.

De esta forma, cuando recibes WM_ENDSESSION tienes la seguridad de que el sistema se va a cerrar.

Sin embargo, actualmente el procesamiento es distinto:

El sistema manda WM_QUERYENDSESSION a todas las aplicaciones. En cuanto una contesta que sí acepta, el sistema inmediatamente le manda WM_ENDSESSION sin esperar a ver qué contestan las demás.

El problema entonces es el siguiente:

Cuando recibes WM_ENDSESSION actuas como si el sistema se va a cerrar, pero suponte que hay otra aplicación, después de la tuya, que no acepta el cierre de sesión.

El efecto será que el sistema no se cierra pero tu aplicación sí.

Para evitar esto yo uso la sigueinte línea al comienzo del dpr de mi aplicación:


SetProcessShutDownParameters($100, 0);


Básicamente, esta línea le dice a Windows en qué orden quiere recibir WM_ENDSESSION. Los de parámetro más bajo reciben el mensaje al último (uso $100 en lugar de 0 porque abajo de $100 está reservado para procesos del sistema)

Ahora, todo esto se basa en que para mi el final de mi sistema coincide con el de la sesión de Windows. A mi me funciona bien pero no sé si te cause conflictos por lo que mencionaste antes:


Resultaria dificil utilizar el cuadro de login de windows, ya que las computadoras de laboratorio de una universidad despues de un tiempo de uso se vuelven lentas, y existiria demasiado tiempo muerto en apagar y prender.

Aquí no se debe apagar la pc pero sí cerrar la sesión de Windows y esto lleva un tiempo.

// Saludos

sakuragi
09-11-2009, 17:39:00
Bueno, después del problema con el foro, vuelvo a poner la duda o problema que tuve al querer probar.


Al modificar la shell, pongo el programa de ejemplo, si me carga al iniciar windows xp, entonces al darle en el botón indicado para ejecutar "explorer.exe", solo me carga el explorador de Windows, no carga el escritorio ni la barra de tareas, no da opción de botón derecho ni nada mas, solamente el administrador de tareas, si pruebo con este en la opción de ejecutar igualmente me carga solo el explorador de windows como lo pongo en esta imagen:
http://s4.subirimagenes.com/otros/3532549loginexorer.jpg


en el codigo para llamar al explorer es este:

Shellexecute (1,nil, 'c:\windows\explorer.exe','','',1);


Pero a un probando sin tener aplicación por explorer, solamente dejando en blanco, y al entrar no sale nada, pero al querer llamarlo por el administrador de tareas en ejecutar, el resultado es el mismo, solo abre el explorador de windows.

:confused:

cualquier observacion se le agradece
saludos

gracias.