(Преобразование c # в Java JNA) - GetModuleFileName от hwnd - PullRequest
1 голос
/ 23 сентября 2011

Я пытаюсь сделать именно то, что делается здесь: Как мне получить GetModuleFileName (), если у меня есть только дескриптор окна (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());

Ответы [ 2 ]

3 голосов
/ 23 сентября 2011

Это может не быть причиной его сбоя, но я думаю, что параметр 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 голос
/ 23 сентября 2011

почему все хлопоты с идентификатором процесса ??

цитируем из документации GetModuleFilename():

hModule [in, необязательно]:

Дескриптор загруженного модуля, путь которого запрашивается.Если этот параметр имеет значение NULL, GetModuleFileName извлекает путь к исполняемому файлу текущего процесса.

если вы хотите указать имя файла модуля текущего процесса, просто передайте NULL как идентификатор процесса.

если вам нужно имя файла модуля другого процесса, вам нужны специальные права доступа перед вызовом OpenProcess().изменение прав доступа описано здесь здесь , и его довольно сложно достичь (требуется большое количество шагов, чтобы найти имя привилегии, получить ее, настроить привилегии токена и т. д.).)

...