我正在开发一个Windows shell扩展,不幸的是,在更改DLL时,我必须重新启动Windows资源管理器(因为它将DLL保存在内存中).
我从Dino Esposito找到了这个程序,但它对我不起作用.
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; }
有人可以分享他们可以分享的东西吗?
PS我意识到我可以去任务管理器并杀死资源管理器进程,但我只是想以懒惰的方式去做.此外,这可实现自动化.
PPS我使用.NET进行开发,但shell重启功能可以是C,C++或.NET语言.它只是一个小的独立可执行文件.
在解析了一些早期的答案并做了一些研究后,我在C#中创建了一个完整的例子.这将关闭资源管理器shell,然后等待它完全关闭并重新启动它.希望这会有所帮助,这个帖子中有很多有趣的信息.
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作为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();
您必须将StartInfo.UseshellExecute设置为true才能使其作为shell重新启动.
一个万无一失的解决方案:
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");