Search code examples
javawindowsjna

GetModuleFileName for window in focus JNA Windows OS


I have created this method that should return the full path and file name so that I can uniquely identify a program. However, it only returns C:\Program Files (x86)\Java\jre6\bin\javaw.exe or an empty string instead of the path for the particular program in focus. What is it that I am doing wrong?

private void getFocusWindow() {
    HWND focusedWindow = User32.INSTANCE.GetForegroundWindow();

    char[] nameName = new char[512];
    User32.INSTANCE.GetWindowModuleFileName(focusedWindow, nameName, 512);

    System.out.println(nameName);
}

Using psapi:

Solution:

Provides full path and module file name, only exception is in eclipse when it prints out '�'. See @technomage's answer for more detail about GetModuleFileNameEx method.

private void getFocusWindow() {
    PsApi psapi = (PsApi) Native.loadLibrary("psapi", PsApi.class);

        HWND focusedWindow = User32.INSTANCE.GetForegroundWindow();
        byte[] name = new byte[1024];

        IntByReference pid = new IntByReference();
        User32.INSTANCE.GetWindowThreadProcessId(focusedWindow, pid);

        HANDLE process = Kernel32.INSTANCE.OpenProcess(0x0400 | 0x0010, false, pid.getValue());
        psapi.GetModuleFileNameExA(process, null, name, 1024);
        String nameString= Native.toString(name);

        System.out.println(nameString);
}

psapi class:

public interface PsApi extends StdCallLibrary {

    int GetModuleFileNameExA(HANDLE process, HANDLE module ,
        byte[] name, int i);

}

Solution

  • GetWindowModuleFileName and GetModuleFileName work only with the current process (i.e. you'll only get useful information for the current process's windows) in Windows NT 4 and later.

    http://support.microsoft.com/?id=228469

    The article recommends using the PSAPI function GetModuleFileNameEx instead.

    EDIT

    You'll need to convert the Window handle to a module handle (which is probably shorter than converting window handle to PID to module handle). Keep in mind that the window handle is just an address (so you'll need the GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS flag).