我在stackoverflow上找到了这个代码,解释了如何获取所有正在运行的进程 在Windows上,这得到名字和pid
Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();
WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
try {
while (kernel32.Process32Next(snapshot, processEntry)) {
System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile));
}
} finally {
kernel32.CloseHandle(snapshot);
}
我的问题是:我如何获得流程路径?
答案 0 :(得分:3)
使用JNA,您需要定义MODULEENTRY32结构并映射一些必需的函数:
import java.util.Arrays;
import java.util.List;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.W32APIOptions;
public interface ProcessPathKernel32 extends Kernel32 {
class MODULEENTRY32 extends Structure {
public static class ByReference extends MODULEENTRY32 implements Structure.ByReference {
public ByReference() {
}
public ByReference(Pointer memory) {
super(memory);
}
}
public MODULEENTRY32() {
dwSize = new WinDef.DWORD(size());
}
public MODULEENTRY32(Pointer memory) {
super(memory);
read();
}
public DWORD dwSize;
public DWORD th32ModuleID;
public DWORD th32ProcessID;
public DWORD GlblcntUsage;
public DWORD ProccntUsage;
public Pointer modBaseAddr;
public DWORD modBaseSize;
public HMODULE hModule;
public char[] szModule = new char[255+1]; // MAX_MODULE_NAME32
public char[] szExePath = new char[MAX_PATH];
public String szModule() { return Native.toString(this.szModule); }
public String szExePath() { return Native.toString(this.szExePath); }
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] {
"dwSize", "th32ModuleID", "th32ProcessID", "GlblcntUsage", "ProccntUsage", "modBaseAddr", "modBaseSize", "hModule", "szModule", "szExePath"
});
}
}
ProcessPathKernel32 INSTANCE = (ProcessPathKernel32)Native.loadLibrary(ProcessPathKernel32.class, W32APIOptions.UNICODE_OPTIONS);
boolean Module32First(HANDLE hSnapshot, MODULEENTRY32.ByReference lpme);
boolean Module32Next(HANDLE hSnapshot, MODULEENTRY32.ByReference lpme);
}
然后检索进程并为每个PID检索模块信息(模块的路径现在可用)。如果从32位进程运行,那么您只能从32位进程获取模块信息(64位进程的路径将为空白)。
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.Tlhelp32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.win32.W32APIOptions;
public class ProcessPathAll {
public static void main(String ... args) {
Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.DEFAULT_OPTIONS);
Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();
WinNT.HANDLE processSnapshot =
kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
try {
while (kernel32.Process32Next(processSnapshot, processEntry)) {
// looks for a specific process
// if (Native.toString(processEntry.szExeFile).equalsIgnoreCase("textpad.exe")) {
System.out.print(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile) + "\t");
WinNT.HANDLE moduleSnapshot =
kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, processEntry.th32ProcessID);
try {
ProcessPathKernel32.MODULEENTRY32.ByReference me = new ProcessPathKernel32.MODULEENTRY32.ByReference();
ProcessPathKernel32.INSTANCE.Module32First(moduleSnapshot, me);
System.out.print(": " + me.szExePath() );
System.out.println();
}
finally {
kernel32.CloseHandle(moduleSnapshot);
}
// }
}
}
finally {
kernel32.CloseHandle(processSnapshot);
}
}
}