7

Windows シェル拡張に取り組んでいますが、残念ながら、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 を使用していますが、シェルの再起動機能は C、C++、または .NET 言語である可能性があります。それは単に小さなスタンドアロンの実行可能ファイルになります。

4

10 に答える 10

14

以前の回答のいくつかを解析し、少し調査した後、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();

    }
}
}
于 2012-05-03T20:17:36.100 に答える
6

Explorer ウィンドウを開くだけでなく、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 を true に設定する必要があります。

于 2011-05-02T02:24:10.057 に答える
5

絶対確実なソリューション:

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");
于 2009-02-22T09:31:34.970 に答える
1

これは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 のシャットダウン ダイアログが表示されます。

于 2009-02-19T15:01:46.197 に答える
1

FindWindow の後、GetWindowThreadProcessId、OpenProcess、TerminateProcess の順に使用します。

于 2009-02-19T13:59:14.413 に答える
1

これは Windows 7/8 用です (テストが必要です。Vista でも動作する可能性があります)。

Windows 7 & 8 に含まれるエクスプローラー(progman)を閉じるには、タスクバー (Win8 では Shell_TrayWnd または Win7 では StartMenu)を Ctrl-Shift を押しながら右クリックするという適切な方法があるため、閉じるための非表示のオプションがポップアップ メニューに表示されます。 Explorer、および Spy++ を使用して掘り下げると、メッセージWM_USER+436によってトリガーされます。

だから私はテストし、次のことを行うとうまくいきます。

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

開いているすべてのインスタンスでエクスプローラーを閉じます。エクスプローラーを再起動するには、上記の方法を使用します。

そのため、これが Windows Vista/7/8 またはその他の 32 ビット/64 ビット版で動作するかどうかをコメントで確認してください。

于 2011-10-03T05:44:40.443 に答える
0

「正しい」エクスプローラ プロセスが強制終了されることをより確実にする AC# ソリューション。

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);
 }
于 2009-09-25T14:27:39.233 に答える