杀死 Windows 资源管理器时出现问题?

发布于 2024-08-27 17:57:02 字数 342 浏览 8 评论 0 原文

我需要终止 Windows 资源管理器的进程 (explorer.exe),因为

可以说我使用本机 NT 方法 TerminateProcess

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

我想通过我的应用程序执行任务管理器正在执行的任何操作。

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

I need to kill windows explorer's process (explorer.exe), for that

lets say i use a native NT method TerminateProcess

It works but the problem is that the explorer starts again, may be windows is doing that, anyway. When i kill explorer.exe with windows task manager, it doesn't come back, its stays killed.

I want to do whatever taskmanager is doing through my application.

Edit:
Thanks to @sblom i solved it, a quick tweak in the registry did the trick. Although its a clever hack, apparently taskmnager has a cleaner way of doing that, that said, i've decided to go with @sblom's way for now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

原谅我要高飞 2024-09-03 17:57:02

来自 Technet

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

From Technet:

You can set the registry key HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoRestartShell to 0, and it will no longer auto-restart.

玻璃人 2024-09-03 17:57:02

“真正的”解决方案。 (完整的程序。经过测试可在 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;
        }
    }
}

The "real" solution. (Complete program. Tested to work on 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;
        }
    }
}
莫多说 2024-09-03 17:57:02

这是此问题的另一个解决方案 - 相反 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 =真)。

编辑: 原始链接已失效,已替换为 Internet Archive Wayback Machine 的缓存。 Windows 2012/2016 的更新文档可在以下位置找到: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill

Here's another solution to this problem - instead api calls it uses an external tool shipped with windows (at least 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);
                }
            }
        }
    }

I know that Win32Exception may not be the best Exception, but this method acts more or less like Kill - with the exception that it actually kills windows explorer.

I've added it as an extension method, so you can use it directly on Process object:

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

You must first ensure that the taskkill tool is available on production environment (it seems that it's been for a while with windows: https://web.archive.org/web/20171016213040/http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/taskkill.mspx?mfr=true).

EDIT: Original link dead, replaced with cache from Internet Archive Wayback Machine. Updated documentation for Windows 2012/2016 can be found at: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill

梦里兽 2024-09-03 17:57:02

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

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

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

What you probably need to do is instead of using TerminateProcess, post a WM_QUIT message to the explorer windows and main thread. It's a bit involved, but I found this page which has some example code that might help you along:

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

Windows will automatically restart explorer.exe after a TerminateProcess so that it restarts in the case of a crash termination.

一场信仰旅途 2024-09-03 17:57:02

我进行了一些研究,结果如下:

Windows 将在关闭后重新启动 资源管理器 -任务管理器除外-。

因此,您应该更改相关的 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();

I have some researches and these are reslts:

Windows will restart explorer after it closed -except by Task Manager-.

So you should change the related 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);

For changing a registry key the program should run as administrator:

  • You can show UAC prompt to user to run application as administrator as explaining in this Answer.
    And if UAC is turned off I direct you to this Answer.
  • You can embed a manifest file in the exe, which will cause Windows Seven to always run the program as an administrator, As explaining in this Answer.
  • You should know you can't force your process starts as administrator; so you can run your process inside your process as another process! You can use this blog post or this answer.
  • You can also use reg command with this [Microsoft Windows Documentation].6.

After setting that -restarting explorer- off: This code can close explorer :

Process[] ps = Process.GetProcessesByName("explorer");
foreach (Process p in ps)
    p.Kill();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文