How to programmatically restart windows explorer process

15,199

Solution 1

A fool-proof solution:

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");

Solution 2

After parsing some of the earlier answers and doing a bit of research, I've created a little complete example in C#. This closes the explorer shell then waits for it to completely shut down and restarts it. Hope this helps, there's a lot of interesting info in this thread.

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();

    }
}
}

Solution 3

I noticed no one addressed the issue of starting explorer.exe as the shell, rather than it just opening an explorer window. Took me a while to figure this out, turns out it was something 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();

You have to set the StartInfo.UseshellExecute as true to get it to restart as the shell.

Solution 4

public static void RestartExplorer()
{
    using(Process process = new Process())
    {
        //有些系统有tskill.exe可以直接调用tskill explorer命令
        process.StartInfo = new ProcessStartInfo
        {
            FileName = "taskkill.exe",
            Arguments = "-f -im explorer.exe",
            WindowStyle = ProcessWindowStyle.Hidden
        };
        process.Start();
        process.WaitForExit();
        process.StartInfo = new ProcessStartInfo("explorer.exe");
        process.Start();
    }
}

Solution 5

After FindWindow use GetWindowThreadProcessId, then OpenProcess, then TerminateProcess.

Share:
15,199
Benoit
Author by

Benoit

Started programming on a good old TRS-80 Model I Spent most of my time working with embedded processors. Everything from 8-bit micros to 32-bit systems. Now teaching for a living.

Updated on June 14, 2022

Comments

  • Benoit
    Benoit almost 2 years

    I'm working on a windows shell extension, and unfortunately, when making changes to the DLL, I must restart windows explorer (since it keeps the DLL in memory).

    I found this program from Dino Esposito, but it doesn't work for me.

    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;
    }
    

    Does any one have something they can share to do this?

    P.S. I realize that I can go to task manager and kill the explorer process, but I just want to do it the lazy way. Besides, this enables automation.

    P.P.S I am using .NET for the development, but the shell restart functionality could be in C, C++ or a .NET language. It will simply be a small stand-alone executable.

  • sharptooth
    sharptooth about 15 years
    That's mostly the same, but requires .NET.
  • Benoit
    Benoit about 15 years
    True, but as I'm doing a .NET Application, that's not an issue
  • sharptooth
    sharptooth about 15 years
    Two points then. First, it's better to test for case insensitive match with "explorer.exe" not to bump occasionally into smth that accidentially contains "explorer" substring. Also will you please edit the question to say explicitly that you use .NET so that I retag the question?
  • Benoit
    Benoit about 15 years
    A bit of flaw in the logic. You'll restart a new explorer process for each one you delete. Put process.Start outside the foreach.
  • itsho
    itsho over 12 years
    Doesn't work on win7 64. it DOES close Explroer, but not re-opens it.
  • gregschlom
    gregschlom over 12 years
    @itsho: it is not supposed to re-open explorer on any Windows version. So it does work on Win7 64. As OP said, you'd then have to use another method to re-open explorer.
  • David Hirst
    David Hirst over 10 years
    Very nice, I took what you have done and made a static class for use within a winform's application and it works perfectly on Windows 7 Pro 64 bit
  • Jorma Rebane
    Jorma Rebane over 9 years
    Sorry for necroing. ShellExecute doesn't work on Windows7/8 -- file copying and icon overlays are broken after executing, no manner of tweaking ShellExecute args seems to help. However plain stdlib.h system("start explorer") call seems to correctly start explorer again.
  • Jorma Rebane
    Jorma Rebane over 9 years
    @itsho: Might be a very late reply, but for 64-bit Windows 7/8 the best and most reliable way to reopen explorer is to use stdlib.h system("start explorer"); call. Using ShellExecute leaves file copying and icon overlays broken.
  • Ryan
    Ryan over 7 years
    Worked for me in Windows 8.1. Thanks!
  • Admin
    Admin almost 7 years
    It seems this is the only proper way to shutdown explorer. But I wonder what is WM_USER + 436 message? It's kind of undocumented feature?
  • brz
    brz about 6 years
    @AlekDepler it's the same like CTRL+SHIFT+Right click on taskbar and choosing "Exit explorer" aka: a way to gracefully exit the windows shell process.
  • AndresRohrAtlasInformatik
    AndresRohrAtlasInformatik almost 2 years
    Didn't do anything on my Windows 10
  • Ravi Patel
    Ravi Patel almost 2 years
    It may not be idle for all use cases, for example, when I change Windows 11 modern context menu to standard and use this method to restart it didn't affect the state of context menu cause it requires restarting explorer process, but it is useful for some things like when I changed file association and triggered this. It immediately shows a new associated app for the file type.