杀死Windows资源管理器的问题?

时间:2010-04-03 04:40:39

标签: c# windows process explorer

我需要杀死Windows资源管理器的进程(explorer.exe),为此

假设我使用本机NT方法TerminateProcess

它可以工作,但问题是资源管理器再次启动,可能是Windows正在这样做,无论如何。当我用Windows任务管理器杀死explorer.exe时,它不会回来,它会被杀死。

我想通过我的应用程序执行任务。

编辑:
感谢@sblom我解决了它,在注册表中快速调整就可以了。虽然它是一个聪明的黑客,但显然是taskmnager有一个更清洁的方式这样做,说,我决定现在用@ sblom的方式。

5 个答案:

答案 0 :(得分:14)

来自Technet

您可以将注册表项HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoRestartShell设置为0,它将不再自动重新启动。

答案 1 :(得分:8)

“真正的”解决方案。 (完整的程序。经测试可在Windows 7上运行。)

using System;
using System.Runtime.InteropServices;

namespace ExplorerZap
{
    class Program
    {
        [DllImport("user32.dll")]
        public static extern int FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool PostMessage(int hWnd, uint Msg, int wParam, int lParam);

        static void Main(string[] args)
        {
            int hwnd;
            hwnd = FindWindow("Progman", null);
            PostMessage(hwnd, /*WM_QUIT*/ 0x12, 0, 0);
            return;
        }
    }
}

答案 2 :(得分:5)

这是另一个解决这个问题的方法 - 而是api调用它使用windows附带的外部工具(至少是Win 7 Professional):

    public static class Extensions
    {
        public static void ForceKill(this Process process)
        {
            using (Process killer = new Process())
            {
                killer.StartInfo.FileName = "taskkill";
                killer.StartInfo.Arguments = string.Format("/f /PID {0}", process.Id);
                killer.StartInfo.CreateNoWindow = true;
                killer.StartInfo.UseShellExecute = false;
                killer.Start();
                killer.WaitForExit();
                if (killer.ExitCode != 0)
                {
                    throw new Win32Exception(killer.ExitCode);
                }
            }
        }
    }

我知道Win32Exception可能不是最好的Exception,但是这个方法或多或少像Kill一样 - 除了它实际上杀死了Windows资源管理器。

我已将其添加为扩展方法,因此您可以直接在Process对象上使用它:

    foreach (Process process in Process.GetProcessesByName("explorer"))
    {
        process.ForceKill();
    }

您必须首先确保taskkill工具在生产环境中可用(似乎已经有一段时间使用windows:https://web.archive.org/web/20171016213040/http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/taskkill.mspx?mfr=true)。

编辑:原始链接已死,替换为来自Internet Archive Wayback Machine的缓存。有关Windows 2012/2016的更新文档,请访问:https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill

答案 3 :(得分:2)

您可能需要做的是不使用TerminateProcess,而是将WM_QUIT消息发布到资源管理器窗口和主线程。它有点牵扯,但我发现这个页面有一些示例代码可以帮助你:

http://www.replicator.org/node/100

Windows会在TerminateProcess之后自动重启explorer.exe,以便在崩溃终止时重新启动。

答案 4 :(得分:0)

我有一些研究,这些是reslts:

  

Windows将在关闭后重新启动explorer - 除了任务管理器 - 。

因此,您应该更改相关的RegistryKey

RegistryKey regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default).OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion\Winlogon", RegistryKeyPermissionCheck.ReadWriteSubTree);
if (regKey.GetValue("AutoRestartShell").ToString() == "1")
    regKey.SetValue("AutoRestartShell", 0, RegistryValueKind.DWord);

要更改注册表项,程序应以管理员身份运行:

  • 您可以向用户显示UAC提示,以管理员身份运行应用程序,并在此Answer中进行说明。 如果关闭UAC,我会引导您进入Answer
  • 您可以在exe中嵌入清单文件,这将导致Windows 7始终以管理员身份运行该程序,如此Answer中所述。
  • 你应该知道你不能以管理员的身份强制你的流程开始;所以你可以在你的流程中运行你的流程作为另一个流程!您可以使用此blog post或此answer
  • 您还可以对此[Microsoft Windows文档]使用reg命令。6

设置后 - 重新启动资源管理器 - 关闭:此代码可以关闭explorer

Process[] ps = Process.GetProcessesByName("explorer");
foreach (Process p in ps)
    p.Kill();