(Converting c# to Java JNA) - GetModuleFileName from hwnd

让人想犯罪 __ 提交于 2019-12-11 08:43:24

问题


I am trying to do exactly what is being done over here: How do I GetModuleFileName() if I only have a window handle (hWnd)?

But in java instead of C#.

So far I have managed to this:

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;



}

The window handle that is given is valid, and the PID is always printed successfully. "Process" appears to return a value but the "result" is always zero. Could anyone knowledgeable about JNA kindly show me where my mistake is?

EDIT: Finally, SUCCESS! The problem was this line (where the first value had to be 1040):

Pointer process = Kernel32.INSTANCE.OpenProcess(1040, false, pid.getValue());

回答1:


This may not be the reason it's failing, but I think the dwProcessId parameter should be an int, not IntByReference.

See 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
);

It's just a regular DWORD.

Also, you can use GetLastError() to return more information about why the function call failed. Finally, this is a long shot, but your declaration of PROCESS_QUERY_INFORMATION is not included in the code snippet -- make sure it has the correct value (0x0400).




回答2:


why all the hassle with the process id ??

quoting from the documention of GetModuleFilename():

hModule [in, optional]:

A handle to the loaded module whose path is being requested. If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.

if you want the module fileName of the current process, just pass NULL as the process id.

if you want the module filename of another process, you need specific access rights before calling OpenProcess(). changing the access rights is described here, and is quite difficult to achieve (it requires a great amount of steps to lookup the privilege name, get the luid of the privilege, adjust the privileges of the token, etc.)



来源:https://stackoverflow.com/questions/7521693/converting-c-sharp-to-java-jna-getmodulefilename-from-hwnd

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!