6

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

假设我使用本机 NT 方法 TerminateProcess

它有效,但问题是资源管理器再次启动,可能是 Windows 正在这样做,无论如何。当我用 Windows 任务管理器杀死 explorer.exe 时,它​​没有回来,它一直被杀死。

我想通过我的应用程序做任何 taskmanager 正在做的事情。

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

4

5 回答 5

15

来自技术网

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

于 2010-04-03T04:50:21.997 回答
9

“真正的”解决方案。(完整程序。经测试可在 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;
        }
    }
}
于 2010-04-03T05:48:17.077 回答
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 可能不是最好的异常,但这种方法的行为或多或少类似于 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

于 2012-10-21T17:02:55.710 回答
2

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

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

Windows 将在 TerminateProcess 之后自动重新启动 explorer.exe,以便在崩溃终止的情况下重新启动。

于 2010-04-03T05:23:17.250 回答
0

我有一些研究,这些是结果:

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 提示,以管理员身份运行应用程序,如本答案中所述。如果 UAC 已关闭,我会将您定向到此答案
  • 您可以在 中嵌入清单文件exe,这将导致 Windows 7 始终以管理员身份运行程序,如本答案中所述。
  • 你应该知道你不能强制你的进程以管理员身份启动;所以你可以在你的进程中运行你的进程作为另一个进程!您可以使用此博客文章或此答案
  • 您也可以reg在此 [Microsoft Windows 文档] 中使用命令。6 .

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

Process[] ps = Process.GetProcessesByName("explorer");
foreach (Process p in ps)
    p.Kill();
于 2015-03-09T15:45:30.107 回答