我正在努力做到这里正在做的事情:How do I GetModuleFileName() if I only have a window handle (hWnd)?
但是在java而不是C#。
到目前为止,我已经成功了:
public static final int PROCESS_QUERY_INFORMATION = 0x0400;
public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
int GetWindowThreadProcessId(HWND hwnd, IntByReference pid);
};
public interface Kernel32 extends StdCallLibrary {
Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
public Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, int dwProcessId);
public int GetTickCount();
};
public interface psapi extends StdCallLibrary {
psapi INSTANCE = (psapi)Native.loadLibrary("psapi", psapi.class);
int GetModuleFileNameExA (Pointer process, Pointer hModule, byte[] lpString, int nMaxCount);
};
public static String getModuleFilename(HWND hwnd)
{
byte[] exePathname = new byte[512];
Pointer zero = new Pointer(0);
IntByReference pid = new IntByReference();
User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid);
System.out.println("PID is " + pid.getValue());
Pointer process = Kernel32.INSTANCE.OpenProcess(PROCESS_QUERY_INFORMATION, false, pid.getValue());
int result = psapi.INSTANCE.GetModuleFileNameExA(process, zero, exePathname, 512);
String text = Native.toString(exePathname).substring(0, result);
return text;
}
给出的窗口句柄有效,并且PID始终成功打印。 “Process
”似乎返回一个值,但“result
”始终为零。任何了解JNA的人都能告诉我我的错误在哪里吗?
编辑:最后,成功!问题是这一行(第一个值必须是1040
):
Pointer process = Kernel32.INSTANCE.OpenProcess(1040, false, pid.getValue());
答案 0 :(得分:3)
这可能不是它失败的原因,但我认为dwProcessId
参数应该是int
,而不是IntByReference
。
请参阅MSDN(http://msdn.microsoft.com/en-us/library/ms684320(v = VS.85).aspx):
HANDLE WINAPI OpenProcess(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwProcessId
);
这只是一个普通的DWORD。
此外,您可以使用GetLastError()返回有关函数调用失败原因的更多信息。最后,这是一个很长的镜头,但您的PROCESS_QUERY_INFORMATION
声明未包含在代码段中 - 请确保它具有正确的值(0x0400)。
答案 1 :(得分:1)
为什么所有的麻烦都与进程id?
引用GetModuleFilename()
的文件:
hModule [in,optional]:
正在请求路径的已加载模块的句柄。如果 此参数为NULL,GetModuleFileName检索该路径 当前进程的可执行文件。
如果你想要当前进程的模块fileName,只需传递NULL
作为进程ID。
如果您需要其他进程的模块文件名,则在调用OpenProcess()
之前需要特定的访问权限。 here描述了更改访问权限,并且很难实现(它需要大量的步骤来查找权限名称,获取权限的luid,调整权限的权限等)< / p>