responde reparar reiniciar problemas nada hacer funcionar finalice explorador dejo deja con archivos .net windows winapi explorer windows-explorer

.net - reparar - Cómo reiniciar programaticamente el proceso de Windows Explorer



reparar explorer.exe windows 10 (8)

Estoy trabajando en una extensión de shell de Windows y, lamentablemente, cuando realizo cambios en la DLL, debo reiniciar Windows Explorer (ya que mantiene la DLL en la memoria).

Encontré este programa de Dino Esposito, pero no funciona para mí.

void SHShellRestart(void) { HWND hwnd; hwnd = FindWindow("Progman", NULL ); PostMessage(hwnd, WM_QUIT, 0, 0 ); ShellExecute(NULL, NULL, "explorer.exe", NULL, NULL, SW_SHOW ); return; }

¿Alguien tiene algo que puedan compartir para hacer esto?

PD. Me doy cuenta de que puedo ir al administrador de tareas y matar el proceso del explorador, pero solo quiero hacerlo de forma perezosa. Además, esto permite la automatización.

PPS Estoy usando .NET para el desarrollo, pero la funcionalidad de reinicio del shell podría estar en C, C ++ o en un lenguaje .NET. Simplemente será un pequeño ejecutable independiente.


Noté que nadie abordó el tema de iniciar explorer.exe como el shell, en lugar de simplemente abrir una ventana del explorador. Me tomó un tiempo resolver esto, resulta que fue algo simple:

string explorer = string.Format("{0}//{1}", Environment.GetEnvironmentVariable("WINDIR"), "explorer.exe"); Process process = new Process(); process.StartInfo.FileName = explorer; process.StartInfo.UseShellExecute = true; process.Start();

Debe establecer StartInfo.UseshellExecute como verdadero para que se reinicie como el shell.


Después de FindWindow use GetWindowThreadProcessId, luego OpenProcess, luego TerminateProcess.


Después de un poco más de google, se me ocurrió la siguiente solución de C #:

using System.Diagnostics; ... static public void RestartExplorer() { foreach(Process p in Process.GetProcesses()) { if(p.MainModule.ModuleName.contains("explorer") == true) p.Kill(); } Process.Start("explorer.exe"); }


Esto funciona para mí en Vista:

DWORD dwPID; HANDLE hExp; HWND hSysTray = ::FindWindow (TEXT("Shell_TrayWnd"), NULL) ; GetWindowThreadProcessId (hSysTray, &dwPID); hExp = OpenProcess (PROCESS_TERMINATE, FALSE, dwPID); if (hExp) { TerminateProcess (hExp, 0); } Sleep (2000); ShellExecute (NULL, NULL, TEXT("explorer.exe"), NULL, NULL, SW_HIDE);

Pero no puedo encontrar ninguna forma de suprimir la ventana de exploración que se abre (lo intenté, de ahí el SW_HIDE). En Vista, ejecutar explorer.exe sin parámetros parece ser lo mismo que ejecutar "explorer.exe / e" en sistemas anteriores. Tendrás que probarlo por ti mismo en XP, no lo tengo aquí.

Nota: Usar TerminateProcess parece extremo, pero publicar un WM_CLOSE en el explorador provoca un cuadro de diálogo de cierre de Windows.


Una solución infalible:

foreach (Process p in Process.GetProcesses()) { // In case we get Access Denied try { if (p.MainModule.FileName.ToLower().EndsWith("://windows//explorer.exe")) { p.Kill(); break; } } catch { } } Process.Start("explorer.exe");


Solución de AC # que proporciona más certeza de que los procesos del explorador "correcto" son eliminados.

using System; using System.Diagnostics; ............... public static void RestartExplorer() { const string explorer = "explorer.exe"; string explorerPath = string.Format("{0}//{1}", Environment.GetEnvironmentVariable("WINDIR"), explorer); foreach (Process process in Process.GetProcesses()) { // In case we get Access Denied try { if (string.Compare(process.MainModule.FileName, explorerPath, StringComparison.OrdinalIgnoreCase) == 0) { process.Kill(); } } catch { } } Process.Start(explorer); }


Esto es para Windows 7/8 (y necesita prueba, tal vez incluso funciona en Vista).

Dado que hay una forma adecuada de cerrar Explorer (progman) incluido en Windows 7 y 8, al hacer clic derecho en la barra de tareas (Shell_TrayWnd en Win8 o StartMenu en Win7) al presionar Ctrl-Shift , se muestra en el menú emergente una opción oculta para cerrar Explorer , y cavando usando Spy ++, se desencadena por el mensaje WM_USER + 436 .

Así que probé y hago lo siguiente, funciona muy bien.

PostMessage(FindWindow(''Shell_TrayWnd''),nil),WM_USER+436,0,0);

Cierra Explorer, con todas las instancias abiertas. Y para reiniciar el explorador, use los métodos provistos arriba.

Por lo tanto, confirme en los comentarios si esto funciona en las ediciones de 32 bits / 64 bits de su Windows Vista / 7/8 o cualquier otro.


Después de analizar algunas de las respuestas anteriores y hacer un poco de investigación, he creado un pequeño ejemplo completo en C #. Esto cierra el shell del explorador y luego espera que se cierre por completo y lo reinicie. Espero que esto ayude, hay mucha información interesante en este hilo.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using System.Threading; namespace RestartExplorer { class Program { [DllImport("user32.dll", SetLastError = true)] static extern bool PostMessage(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)] uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); const int WM_USER = 0x0400; //http://msdn.microsoft.com/en-us/library/windows/desktop/ms644931(v=vs.85).aspx static void Main(string[] args) { try { var ptr = FindWindow("Shell_TrayWnd", null); Console.WriteLine("INIT PTR: {0}", ptr.ToInt32()); PostMessage(ptr, WM_USER + 436, (IntPtr)0, (IntPtr)0); do { ptr = FindWindow("Shell_TrayWnd", null); Console.WriteLine("PTR: {0}", ptr.ToInt32()); if (ptr.ToInt32() == 0) { Console.WriteLine("Success. Breaking out of loop."); break; } Thread.Sleep(1000); } while (true); } catch (Exception ex) { Console.WriteLine("{0} {1}", ex.Message, ex.StackTrace); } Console.WriteLine("Restarting the shell."); string explorer = string.Format("{0}//{1}", Environment.GetEnvironmentVariable("WINDIR"), "explorer.exe"); Process process = new Process(); process.StartInfo.FileName = explorer; process.StartInfo.UseShellExecute = true; process.Start(); Console.ReadLine(); } } }