获取给定进程句柄的运行进程

10

如果我已经知道句柄,有没有人能告诉我如何使用进程类(Process Class)在C#中捕获正在运行的进程?

我不想使用枚举(getrunning processes method)来获取进程。如果可能的话,可以使用pInvoke。

5个回答

10
在纯粹的C#中,看起来你必须循环遍历它们所有:
// IntPtr myHandle = ...
Process myProcess = Process.GetProcesses().Single(
    p => p.Id != 0 && p.Handle == myHandle);
上面的示例在找不到句柄时会有意地失败。否则,你当然可以使用SingleOrDefault。显然,它不喜欢你请求进程ID 0的句柄,因此需要额外的条件。
使用WINAPI,你可以使用GetProcessId。我在pinvoke.net上找不到它,但下面的代码可以用:
[DllImport("kernel32.dll")]
static extern int GetProcessId(IntPtr handle);

(签名使用 DWORD ,但在.NET BCL中,进程ID由 int 表示)

然而,拥有句柄而没有进程ID似乎有点奇怪。调用OpenProcess获取进程句柄时需要提供进程ID。


1
我收到一个访问被拒绝的消息(Win32 异常)? - Grant
已经修复,但也许你应该使用WINAPI。毕竟这是你最初的选择 :) - Thorarin
1
process.handle 给出了访问被拒绝的错误,但是 process.MainWindowHandle 可以无误运行。 - bh_earth0
糟糕的-1... MainWindowHandle 是完全不同的东西。 - Latency

3
using System.Diagnostics;

class ProcessHandler {
    public static Process FindProcess( IntPtr yourHandle ) {
        foreach (Process p in Process.GetProcesses()) {
            if (p.Handle == yourHandle) {
                return p;
            }
        }

        return null;
    }
}

1

我长期以来一直在使用这些方法:

    public static Process FindProcess(IntPtr handle) => FindProcess(p => p.Handle == handle);
    public static Process FindProcess(int id) => FindProcess(p => p.Id == id);
    public static Process FindProcess(string title) => FindProcess(p=> p.MainWindowTitle == title);
    public static Process FindProcess(Func<Process,bool> comparer)
    {
        foreach (Process p in Process.GetProcesses())
            if (comparer(p))
                return p;
        return null;
    }

Enjoy...


1

似乎没有通过 .Net API 简单的方法来实现这个。问题是,你从哪里得到了那个句柄?如果你可以通过相同的方式获取进程 ID 的访问权限,你可以使用:

Process.GetProcessById(int iD)


通过ID获取肯定更好/更容易,但是通过句柄也是可能的。请参阅其他答案。 - Thorarin
一个API公开了HWND但没有ID。 - Grant
问题仍然存在,句柄从哪里来。如果使用Win32 API,则可能需要发出另一个API调用以从句柄中获取进程ID。 另一个问题是,句柄仅在同一进程内有效,而ID是系统范围内有效的。 - Frank Bollack
是的,我同意只有句柄而没有ID很奇怪。 - Thorarin

0

那个需要一个窗口句柄。他有一个进程句柄。WINAPI的GetProcessId是他所需要的。 - Thorarin

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