8

在 .NETProcess.GetProcessById中,如果具有此 ID 的进程未运行,则会引发异常。如何安全地调用此方法使其不会引发异常?我在想类似的东西

if(Process.IsRunning(id)) return Process.GetProcessById(id);
else return null; //or do something else

但是找不到任何检查ID的方法,除了可能获取所有正在运行的进程并检查ID是否存在于列表中。

4

4 回答 4

15
public Process GetProcByID(int id)
{
    Process[] processlist = Process.GetProcesses();
    return processlist.FirstOrDefault(pr => pr.Id == id);
}

我看了里面的Process.GetProcessById方法。

它使用内部静态类 ProcessManager 来确保该进程运行。ProcessManager 获取当前在系统中运行的所有进程并检查那里的 id,所以我认为这是最好的方法。

所以你应该考虑异常的开销或Process数组的开销。

于 2013-02-20T09:06:55.207 回答
3

只需使用 try-catch 块

Process p = null;
try{
  p = Process.GetProcessById(id);
}
catch(Exception){

}
return p;
于 2013-02-20T09:00:48.427 回答
1

是的,使用 try + catch 可能会成功。如果进程没有运行,则不会发生任何事情,而是抛出异常。

于 2013-02-20T09:06:02.657 回答
0

使用 pinvoke 的相同代码,这应该比 GetProcesses 更快,因为它不需要枚举所有进程。

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags access, bool inheritHandle, int procId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode);

[Flags]
public enum ProcessAccessFlags : uint
{
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VirtualMemoryOperation = 0x00000008,
    VirtualMemoryRead = 0x00000010,
    VirtualMemoryWrite = 0x00000020,
    DuplicateHandle = 0x00000040,
    CreateProcess = 0x000000080,
    SetQuota = 0x00000100,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    QueryLimitedInformation = 0x00001000,
    Synchronize = 0x00100000
}


/// <summary>
/// Checks if given process is still alive
/// </summary>
/// <param name="processId">process id</param>
/// <returns>true if process is alive, false if not</returns>
static public bool IsProcessAlive(int processId)
{
    IntPtr h = OpenProcess(ProcessAccessFlags.QueryInformation, true, processId);

    if (h == IntPtr.Zero)
        return false;

    uint code = 0;
    bool b = GetExitCodeProcess(h, out code);
    CloseHandle(h);

    if (b)
        b = (code == 259) /* STILL_ACTIVE  */;

    return b;
}
于 2019-02-16T21:21:16.177 回答