sábado, 5 de noviembre de 2011

Cómo reiniciar explorer.exe en Windows Vista/7/8 de forma segura [Delphi]


Muchas veces deseamos reiniciar el explorador de Windows ya sea para aplicar cambios hechos al modificar el mismo explorer, modulos activex que requieren reiniciar explorer, modificaciones al registro de windows entre otras cosas.

En mi caso es la de reiniciar Windows Explorer para cambiar entre el entorno anterior de Windows 8 y el entorno Metro Style.

Pero dejando de lado eso, muchos recurren a matar el proceso del explorador de windows, otros recurren a comandos internos como taskkill entre otras maneras que finalmente eliminan explorer de la memoria, sin embargo existen procesos dependientes de explorer que requieren de un cierre adecuado del explorador, ya sea objetos ShellObj u otros.

Debido a estas razones (pérdida de datos, corrupción de archivos), no es muy recomendable eliminar el explorador de windows de esa manera, por lo tanto, la mejor manera es utilizando el propio método que ofrece tanto Windows Vista, 7 y 8.

El método consiste en presionar Ctrl-Shift y hacer clic derecho en un área vacía del menú inicio, éste mostrará un menú desplegable con la opción escondida de Salir de Explorer.

Exit-Explorer

Bueno, pero como programador, eso no nos interesa, lo que sí interesa es cómo aprovechar esa característica para poder utilizarlo en nuestras aplicaciones (utilitarios) y cerrar Explorer de manera segura.

Utilizando Spy++ para espíar ese proceso, me di con el siguiente mensaje que recibe la barra de tareas para poder cerrar Windows Explorer, el mensaje es WM_USER+436, así que para cerrar el explorador de windows con todas sus instancias abiertas, basta con enviar este mensaje a la barra de tareas.

El código es el siguiente:

PostMessage(FindWindow('Shell_TrayWnd'),nil),WM_USER+436,0,0); Sleep(1000); //esperamos un segundo al menos WinExec('explorer.exe',SW_NORMAL); //y volvemos a ejecutar explorer

Con eso basta para que nuestra aplicación pueda reiniciar el explorador de Windows.

Un proyecto de Ejemplo

Para este ejemplo utilizaré Delphi XE2, cualquier otra versión, inclusive Lazarus, permite realizar lo anterior.

Explorer-Restart

File->New->VCL Forms Application – Dephi

Agregamos al formulario un TButton y un TTimer

restarexplorer

Deshabilitamos Timer1 (Enabled:=False)

restarexplorer[3]

Hacemos doble clic al botón y escribimos el siguiente código:

procedure TForm1.Button1Click(Sender: TObject); begin PostMessage(FindWindow('Shell_TrayWnd',nil),WM_USER+436,0,0); Sleep(1000); //esperamos un segundo al menos Timer1.Enabled:=true; end;

Finalmente agregamos este otro pedazo de código a Timer1:

procedure TForm1.Timer1Timer(Sender: TObject); begin if FindWindow('Shell_TrayWnd',nil)=0 then begin WinExec('explorer.exe',SW_NORMAL); //y volvemos a ejecutar explorer Timer1.Enabled:=false; end; end;

 

Ahora sólo queda probar, presionamos F9 y ya podemos ver funcionando a nuestro pequeño utilitario.

RestartExplorer

Explicación:

El botón enviará un mensaje a la barra de tareas, el cual cerrará inmediatamente todas las instancias abiertas del explorador de Windows, y luego activará al temporizador (Timer), este último se encargará de verificar si ya se cerró la barra de tareas, y cuando sea así, volverá a lanzar explorer.exe quien es el que contiene a la barra de tareas, una vez hecho eso, el timer se desactivará.

Codigo fuente ~> RestartDesktop.zip (80KB) <~ al descargar cambiar de extensión a .zip