【发布时间】:2023-03-19 12:10:01
【问题描述】:
我正在尝试从机器中获取进程并为每个进程收集相关信息。
我在 JNA 的帮助下用 Java 编写了这个功能
public static List<ProcessInfo> getProcessList() throws Exception {
/* Initialize the empty process list. */
List<ProcessInfo> processList = new ArrayList<ProcessInfo>();
/* Create the process snapshot. */
WinNT.HANDLE snapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
Tlhelp32.PROCESSENTRY32.ByReference pe = new Tlhelp32.PROCESSENTRY32.ByReference();
for (boolean more = Kernel32.INSTANCE.Process32First(snapshot, pe); more; more = Kernel32.INSTANCE.Process32Next(snapshot, pe)) {
/* Open this process; ignore processes that we cannot open. */
WinNT.HANDLE hProcess = Kernel32.INSTANCE.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION, /* PROCESS_QUERY_LIMITED_INFORMATION */false, pe.th32ProcessID.intValue());
if (hProcess == null) {
continue;
}
/* Get the image name. */
char[] imageNameChars = new char[1024];
IntByReference imageNameLen = new IntByReference(imageNameChars.length);
if (!Kernel32.INSTANCE.QueryFullProcessImageName(hProcess, 0, imageNameChars, imageNameLen)) {
throw new Exception("Couldn't get process image name for "
+ pe.th32ProcessID.intValue());
}
/* Add the process info to our list. */
processList.add(new ProcessInfo(pe.th32ProcessID.intValue(), pe.th32ParentProcessID.intValue(), new String(imageNameChars, 0, imageNameLen.getValue())));
/* Close the process handle. */
Kernel32.INSTANCE.CloseHandle(hProcess);
}
/* Close the process snapshot. */
Kernel32.INSTANCE.CloseHandle(snapshot);
/* Return the process list. */
return processList;
}
现在我在 OpenProcess 函数上收到错误 (87)。这段代码在用户会话中运行,我得到了结果,但是在从本地系统的窗口服务运行这段代码时,它失败了。
【问题讨论】:
-
您只能通过这种方式收集有关您自己流程的信息。您可能会发现 this code 很有用。
-
你如何确保你失败了?两种方式都会获取系统进程,
OpenProcess会失败并返回NULL,然后继续for循环,没有任何错误信息。所以用户会话看起来似乎工作。 -
另外,如果某个进程在
CreateToolhelp32Snapshot和OpenProcess之间被杀死,它将无法通过id找到该进程并返回ERROR_INVALID_PARAMETER