문제

Windows Shell Extension에서 작업하고 있으며 불행히도 DLL을 변경할 때 Windows Explorer를 다시 시작해야합니다 (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;
}

이 작업을 수행하기 위해 공유 할 수있는 일이 있습니까?

추신 : 나는 작업 관리자에게 가서 탐색기 프로세스를 죽일 수 있다는 것을 알고 있지만 게으른 방식으로하고 싶습니다. 게다가, 이것은 자동화를 가능하게합니다.

pps 나는 개발에 .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#에서 약간의 완전한 예를 만들었습니다. 이것은 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 Window를 열기보다는 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로 설정해야합니다.

FindWindow가 GetWindowThreadProcessid를 사용한 다음 OpenProcess를 사용한 다음 종료 프로세스를 사용하십시오.

좀 더 인터넷 검색을 한 후 다음 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를 사용하면 극단적 인 것처럼 보이지만 Explorer에 WM_CLOSE를 게시하면 Windows Shutdown 대화 상자가 발생합니다.

이것은 Windows 7/8을위한 것입니다 (테스트가 필요하고 Vista에서도 작동 할 수도 있습니다).

부터 탐험가를 닫는 적절한 방법이 있습니다 (Progman) Windows 7 & 8에 포함 - 마우스 오른쪽 버튼을 클릭하여 작업 표시 줄 (Win8의 Shell_traywnd 또는 Win7의 STARTMENU) Ctrl-Shift를 누르는 동안, 팝업 메뉴에 표시됩니다 탐험가를 닫는 숨겨진 옵션, 스파이 ++를 사용하여 파기 메시지로 트리거됩니다. WM_USER+436.

그래서 나는 다음을 테스트하고 다음과 같이 잘 작동합니다.

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

모든 열린 인스턴스와 함께 탐색기를 닫습니다. 탐색기를 다시 시작하려면 위에 제공된 방법을 사용하십시오.

그래서, 확인 해주세요 댓글에서 이것이 Windows Vista/7/8의 32bit/64 비트 에디션에서 작동하는 경우.

"올바른"탐색기 프로세스가 사망한다는 확실성을 제공하는 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);
 }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top