我工作的一个Windows外壳扩展,不幸的是,在更改DLL时,我必须重新启动Windows资源管理器(它保存在内存中的DLL)。

我发现从恐龙埃斯波西托这个程序,但它并没有为我工作。

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

没有任何一个有东西,他们可以分享到这样做呢?

P.S。我意识到,我可以去任务管理器,并杀死explorer进程,但我只是想做到这一点偷懒的方法。此外,这使得能够自动化。

P.P.S我使用.NET的开发,但外壳重新启动功能可以是C,C ++或.NET语言。这将简单地是一个小的独立的可执行文件。

有帮助吗?

解决方案

一个防呆溶液:

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

其他提示

解析一些早期的答案,做了一些研究之后,我创建了一个C#有点完整的例子。这将关闭,然后在资源管理器外壳等待其完全关闭并重新启动它。希望这有助于,有很多有趣的信息在这个线程。

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

    }
}
}

我发现没有人解决的explorer.exe启动的问题作为外壳,而不是它只是打开一个浏览器窗口。我花了一段时间才能弄清楚这一点,事实证明这是一件简单的:

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

您必须设置StartInfo.UseshellExecute作为真正得到它的重新启动作为外壳。

在FindWindow函数使用GetWindowThreadProcessId,然后OpenProcess,然后了TerminateProcess。

一些更多的googling后,我想出了下面的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");
}

这对我的作品在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);

但我找不到任何办法来抑制打开(我试过了,因此SW_HIDE)的探索窗口。在Vista中,不带参数运行Explorer.exe的似乎是与运行“的explorer.exe / e”的较早系统。你必须自己试一试在XP,我没有在这里。

请注意:使用了TerminateProcess似乎偏激,但张贴WM_CLOSE到探险家挑起一个Windows关机对话框

这是Windows 7/8(并且需要测试,甚至适用于Vista的)。

由于的有一个适当的方式来关闭浏览器(普罗格曼)包括在Windows 7&8 - 的通过右击在任务栏(Shell_TrayWnd在Win7的Win8的或的StartMenu)的而按下Ctrl移下,它显示在弹出菜单中的隐藏选项关闭浏览器,然后使用间谍挖它++它是由消息的 WM_USER + 436 <触发/强>

所以,我测试,执行以下操作它的伟大工程。

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

有关闭资源管理器,与所有的开实例。并重新启动资源管理器,使用上面提供的方法。

因此,请确认在评论这是否对你的Windows Vista / 7/8或任何其他的32位/ 64位版本。

一个C#解决方案,提供更可靠的是,“右” Explorer进程丧命。

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);
 }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top