像任务管理器(Windows 8)一样杀死进程,因为访问被拒绝

Posted

技术标签:

【中文标题】像任务管理器(Windows 8)一样杀死进程,因为访问被拒绝【英文标题】:Kill Process like Task Manager (Windows 8) do, because of access denied 【发布时间】:2015-05-02 10:42:05 【问题描述】:

我有以下问题: 我尝试从 c# 代码中终止在线游戏的进程。我总是得到“拒绝访问”!它有一个 Anti Hack Shield,我认为这就是问题所在......

[编辑] 我将 /T 添加到 TaskKill 命令行,现在得到带有 PID“访问被拒绝”的错误子进程。 我在 Process.GetProcessById() 和主进程的线程列表中都找不到这个 PID。有人知道如何找到这个吗?

但是使用窗口任务管理器我可以杀死它! 我通过使用 P/invoke FindWindow() 和 GetWindowThreadProcessId() 找到窗口来获取我的进程 我检查了PID它是一样的! 我使用 P/Invoke 是因为 SetFourgroundWindow() 无论如何我都需要它

我还发现它在内核模式下处于活动状态[1] 这是一个在线游戏,所以它使用网络适配器,这可能是问题吗?但为什么我可以用任务管理器杀死它? 在这种情况下,我找到了 SetKernelObjectSecurity:http://csharptest.net/coding/ 我不确定我是否做对了,我只是将 AceQualifier.AccessDenied 更改为 AccessAllowed not working。

那么我怎样才能像任务管理器一样杀死它呢? 或者我可以调用任务管理器的方法吗? 也许我之前需要更改一些参数/权限?

我搜索并找到了 SeDebugPrivilege 的内容:[2] 我使用了它,但仍然是“拒绝访问”我也尝试了 Process.EnterDebugMode();

这是我尝试过的方法:我以管理员身份运行 Visual Studio

public void KillKal(IntPtr _WindowPointer)

    uint ProcessID;

    GetWindowThreadProcessId(_WindowPointer, out ProcessID);
    try
    
        #region SeDebugPrivilege 
        IntPtr hToken;
        LUID luidSEDebugNameValue;
        TOKEN_PRIVILEGES tkpPrivileges;

        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken))
        
            Console.WriteLine("OpenProcessToken() failed, error = 0 . SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
            return;
        
        else
        
            Console.WriteLine("OpenProcessToken() successfully");
        

        if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out luidSEDebugNameValue))
        
            Console.WriteLine("LookupPrivilegeValue() failed, error = 0 .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
            CloseHandle(hToken);
            return;
        
        else
        
            Console.WriteLine("LookupPrivilegeValue() successfully");
        

        tkpPrivileges.PrivilegeCount = 1;
        tkpPrivileges.Luid = luidSEDebugNameValue;
        tkpPrivileges.Attributes = SE_PRIVILEGE_ENABLED;

        if (!AdjustTokenPrivileges(hToken, false, ref tkpPrivileges, 0, IntPtr.Zero, IntPtr.Zero))
        
            Console.WriteLine("LookupPrivilegeValue() failed, error = 0 .SeDebugPrivilege is not available", Marshal.GetLastWin32Error());
        
        else
        
            Console.WriteLine("SeDebugPrivilege is now available");
        

        Process.EnterDebugMode();
        #endregion SeDebugPrivilege
        Process p = Process.GetProcessById((int)ProcessID);

        //1. try
        Process.Start(new ProcessStartInfo
        
            FileName = "cmd.exe",
            CreateNoWindow = true,
            UseShellExecute = false,
            Verb = "runas",
            Arguments = string.Format("/c taskkill /pid 0 /f", ProcessID)
        );
        //2.try
        Process.Start(new ProcessStartInfo
        
            FileName = "net.exe",
            CreateNoWindow = true,
            UseShellExecute = false,
            Verb = "runas",
            Arguments = string.Format("stop 0", p.ProcessName)
        );
        //3. try
        Process.Start("cmd", string.Format("/c \"taskkill /f /pid 0\"", ProcessID));

        //4. try get exception: access denided
        p.Kill();

        //5. try get exception:Process must exit before requested information can be determined.
        TerminateProcess(p.Handle, (uint)p.ExitCode);
    
    catch (Exception e)
    
        MessageBox.Show(e.ToString());
    

我还尝试在管理 cmd 中使用 PsKill 和 task kill ! https://postimg.org/image/qp5nkjvtn/

[1]http://***.com/questions/14038165/kill-process-windows-8-issues

[2]http://hintdesk.com/c-how-to-enable-sedebugprivilege/

【问题讨论】:

【参考方案1】:

如果你想以这种方式实现,你必须以管理员身份运行 VS,并且应该运行

Process.Start("cmd", string.Format("/c \"taskkill /f /pid 0\"", ProcessID));

也以管理员身份。

您应该使用ProcessStartInfo 类来运行这样的命令:

ProcessStartInfo info = new ProcessStartInfo(@"C:\Windows\Notepad.exe");
info.UseShellExecute = true;
//The magic happens here
info.Verb = "runas";
Process.Start(info);

编辑

你还必须杀死子进程,所以taskkill命令的参数应该是:taskkill /T /F /pid 0

【讨论】:

使用 cmd 为您提供正确的解决方案。但正如您在这里看到的,它仍然无法正常工作postimg.org/image/qp5nkjvtn 谢谢。你是对的,问题是一个子进程。但是知道我得到带有 PID“访问被拒绝”的错误子进程。我在 Process.GetProcessById() 和主进程的线程列表中都找不到这个 PID。你知道跟踪这个进程的方法吗?我会将其添加到我的问题中。 @StefanErler 如果您仍然被拒绝访问,那么即使您认为您正在以管理员身份运行程序,您也可能不是. @ScottChamberlain 我以管理员身份运行 VisualStudio,您可以在此处看到 postimg.org/image/trok06ia7。我还尝试运行发布文件 AS Administrator。我成功杀死了 Winrar.exe。所以我认为我处于管理员模式。 对不起,我错过了你的回复。我将尝试在大约 6-7 小时内回答(何时在家)。感谢您的耐心等待,我们的航班仍在继续:)

以上是关于像任务管理器(Windows 8)一样杀死进程,因为访问被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

ubuntu12.04如何打开像任务管理器一样的东西?见过,现在忘了

Delphi 7 - 防止用户在任务管理器中杀死进程

任务管理器杀死进程

Android:如果任务管理器杀死,则重新调用应用程序

防止从任务管理器中杀死进程,反转

Linux里面top相当于windows下任务管理器吗?