Dot-Net

如何以程式方式重新啟動 Windows 資源管理器程序

  • June 18, 2022

我正在開發 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# 中創建了一個完整的小範例。這將關閉 explorer 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 重新啟動。

引用自:https://stackoverflow.com/questions/565405