进程.Kill() 访问被拒绝

24
当我运行以下代码时,会抛出一个Win32Exception访问被拒绝。我在搜索中找不到任何解决方案。我该如何修复?
foreach (ListViewItem list in showprocesses.SelectedItems)
{
    Process p = System.Diagnostics.Process.GetProcessById(Convert.ToInt32(list.Tag));
    if (p != null)
        p.Kill();
}

它试图终止哪个进程? - Arran
你是针对所有尝试的进程还是某些特定进程出现异常? - Sriram Sakthivel
@SriramSakthivel 任何进程 http://screenshu.com/static/uploads/temporary/a7/1c/gg/1no2yr.jpg - Ezzy
1
我发现另一个原因是:我正在尝试从32位进程中结束64位进程。我正在使用“启用32位应用程序”设置在IIS下运行的Web应用程序中创建Excel自动化对象。这意味着IIS正在运行32位。安装的Excel版本为64位。创建/使用Excel对象没有问题,但我无法通过Process.Kill关闭它(这不应该是必要的,但这是另一个问题)。 - dudeNumber4
6个回答

17
通常情况下,如果您没有必要的权限,就会出现这个错误。您必须是管理员,并且在Windows Vista及以上版本中,以提升的模式运行您的应用程序/进程。此外,有一些被认为是系统关键的进程,即使作为管理员,您也无法终止它们,可能需要以“system”身份运行,还有一些连系统也无法终止的进程,比如杀毒软件或实际病毒,因为它们不希望您终止它们的进程。
另一个可能性是,如果进程已经在终止中,它也会抛出该异常,请参阅MSDN

1
我的应用程序在管理员模式下运行。 我试图关闭像Spotify等进程。 - Ezzy
你尝试过在应用程序外部结束它吗?尝试下载pskill,http://technet.microsoft.com/en-us/sysinternals/bb896683.aspx,并尝试使用该应用程序结束它。如果可以,请检查您的应用程序是否存在问题(未以提升模式运行?在“p”中选择了错误的进程?),请记得以提升的方式运行cmd提示符,然后从该提升的cmd提示符调用pskill。 - Jason
1
我试图用这段代码关闭 Spotify: '//foreach (Process proc in Process.GetProcessesByName("spotify")) //{ // proc.Kill(); //}' 它完美地运行了。看起来我的原始代码不起作用。那么我必须再看一下。现在,至少我可以排除管理员权限问题。 - Ezzy
尝试 { int procID = System.Convert.ToInt32(showprocesses.SelectedItems[0].SubItems[1].Text); Process tempProc = Process.GetProcessById(procID); tempProc.Kill(); } 捕获异常 { MessageBox.Show("无法终止进程", "错误"); }看起来我对代码进行了一些调整,这样就可以轻松地杀死所选进程 :) - Ezzy

4

我曾经在Windows 8.1下遇到了一个Delphi应用程序的问题。 我的应用程序关闭了,但仍然在任务管理器的后台进程中。 使用TaskKill无法结束它(尝试过管理员模式,“/F”选项,从命令行...) 最终我发现Windows“标记”了我的应用程序的一个DLL为“IgnoreFreeLibrary”。 这就是为什么我的应用程序无法关闭的原因。 以下是注册表的摘录:

[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"{MyApplicationPathAndExeName}"="$ IgnoreFreeLibrary<DllWithProblemName.Dll>"

我删除了注册表项,一切恢复正常。


3

我曾经遇到了同样的问题,使用以下代码解决了这个问题:

    [DllImport("user32.dll")]
    public static extern int FindWindow(string ClassName, string WindowName);

    [DllImport("user32.dll")]
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

    public const int WM_SYSCOMMAND = 0x0112;
    public const int SC_CLOSE = 0xF060;

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        int HWND = FindWindow(null, "My Window");//window title

        SendMessage(HWND, WM_SYSCOMMAND, SC_CLOSE, 0);
    }

您的回答与此问题相关吗? - Gholamali Irani
当你使用p.Kill()时,会出现Win32异常,因此你需要使用user32.dll来关闭其他程序或程序集的窗口。 - Hamed Rezaei
我认为应该是 SendMessage 的第一个参数 IntPtr 而不是 int。 - yhackup

1
这是我的ForceKill的核心。 它首先尝试使用.Kill()结束进程。 然后尝试通过taskkill终止进程,然后尝试通过wmic终止进程。
    public static void ForceKill(Process proc)
    {
        // Will only work if started by this instance of the dll.
        try { proc.Kill(); } catch (Exception ex) { }

        // Fallback to task kill
        var taskKilPsi = new ProcessStartInfo("taskkill");
        taskKilPsi.Arguments = $"/pid {proc.Id} /T /F";
        taskKilPsi.WindowStyle = ProcessWindowStyle.Hidden;
        taskKilPsi.UseShellExecute = false;
        taskKilPsi.RedirectStandardOutput = true;
        taskKilPsi.RedirectStandardError = true;
        taskKilPsi.CreateNoWindow = true;
        var taskKillProc = Process.Start(taskKilPsi);
        taskKillProc.WaitForExit();
        string taskKillOutput = taskKillProc.StandardOutput.ReadToEnd(); // Contains success
        string taskKillErrorOutput = taskKillProc.StandardError.ReadToEnd();

        // Fallback to wmic deelete process.
        var wmicPsi = new ProcessStartInfo("wmic");
        wmicPsi.Arguments = $@"process where ""name='{proc.ProcessName}.exe'"" delete";
        wmicPsi.WindowStyle = ProcessWindowStyle.Hidden;
        wmicPsi.UseShellExecute = false;
        wmicPsi.RedirectStandardOutput = true;
        wmicPsi.RedirectStandardError = true;
        wmicPsi.CreateNoWindow = true;
        var wmicProc = Process.Start(wmicPsi);
        wmicProc.WaitForExit();
        string wmicOutput = wmicProc.StandardOutput.ReadToEnd(); // Contains success
        string wmicErrorOutput = wmicProc.StandardError.ReadToEnd();

    }

你可以检查proc.Kill()是否成功,或者检查taskKillOutputwmicOutputsuccess,而不是每次都使用这三种方法。

我发现对于由管理员启动的进程,proc.Kill()会失败,但只要不是某种受保护的系统进程,taskkillwmic似乎都能正常工作。


-3

尝试 { pyProcess.Kill(); } catch (Exception error) { Console.WriteLine(error.ToString()); }

无需管理员访问权限。但这仅适用于某些进程。


-4

在Windows上禁用UAC可以解决这个问题。


3
请提供如何执行该操作的说明,这将是有帮助的。 - mypetlion
9
不要真的这样做。这是可怕的建议。 - Peter W.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接