【发布时间】:2011-09-30 17:40:45
【问题描述】:
我对 JNA 有一个非常奇怪的问题。 我正在使用 GetExitCodeProcess() 检查进程是否存在。
例如,我知道记事本是 PID 2084。当我使用我的方法检查 PID 2084 是否存在时,它会为 2084 到 2087 之间的 PID 返回 true(即使我完全确定 PID 2085-2087 不存在)存在)。对于其他 PID,如 2083 和 2088,它返回 false。
就好像存在某种不可能的舍入错误,OpenProcess() 正在打开一个不存在的 PID 的句柄!
这发生在所有进程中。如果我枚举所有进程并调用 isRunning(PID),它会在 PID + 1,2 or 3 存在时返回 true。否则它返回 false,所以至少它在部分工作。
模式始终相同,在PID和PID + 3之间返回true。
示例输出:
[Notepad PID = 2084, cmd.exe PID = 2100]
isRunning(2083)=False
isRunning(2084)=true
isRunning(2085)=true
isRunning(2086)=true
isRunning(2087)=true
isRunning(2088)=false
.... false .....
isRunning(2100)=true
等等。
Interface code:
protected interface Kernel32 extends StdCallLibrary {
Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
public Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, int dwProcessId);
int GetLastError();
boolean GetExitCodeProcess(Pointer hProcess, IntByReference lpExitCode);
};
Function code:
public static boolean isRunning(int pid)
{
final int PROCESS_QUERY_INFORMATION = 0x0400;
final int STILL_ALIVE = 259;
final int INVALID_PARAM = 87;
Pointer hProcess = kernel32.OpenProcess(PROCESS_QUERY_INFORMATION, false, pid);
int error = kernel32.GetLastError();
if (error == INVALID_PARAM)
return false; //Invalid parameter.
IntByReference exitCode = new IntByReference();
kernel32.GetExitCodeProcess(hProcess, exitCode);
if (exitCode.getValue() != STILL_ALIVE)
return false;
else
return true;
}
public static void main(String[] args) {
System.out.println(isRunning(2083)); //Proceses with PID 2083, 2085 to 2088 do not exist.
System.out.println(isRunning(2084)); //2084 is notepad
System.out.println(isRunning(2085));
System.out.println(isRunning(2086));
System.out.println(isRunning(2087));
System.out.println(isRunning(2088));
}
【问题讨论】: