Uzyskiwanie informacji o aktywnym oknie w Javie

Próbuję uaktualnić moją aplikację w Javie, aby działała tylko wtedy, gdy aktywne jest okno procesu o określonej nazwie. Dowiedziałem się, że jest to możliwe za pomocą JNI, ale nie mam pojęcia, jak dokładnie to zrobić. Po prostu nie mogłem znaleźć żadnego opisu ani przykładu, który by to wyjaśniał. Moje pytanie brzmi - jak uzyskać nazwę procesu aktualnie aktywnego okna w Windows (poprzez JNI, lub cokolwiek innego - akceptuję jakieś inne rozwiązanie)?

Author: Hovercraft Full Of Eels, 2011-06-17

2 answers

Oszczędź sobie bólu i użyj JNA . Musisz pobrać jna.jar i JNA-Platforma.jar {[7] } Dla API Win32. Wiki pinvoke i MSDN są przydatne do znajdowania właściwych wywołań systemowych.

W każdym razie, oto kod do wydrukowania tytułu i procesu aktualnie aktywnego okna.

import static enumeration.EnumerateWindows.Kernel32.*;
import static enumeration.EnumerateWindows.Psapi.*;
import static enumeration.EnumerateWindows.User32DLL.*;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.ptr.PointerByReference;

public class EnumerateWindows {
    private static final int MAX_TITLE_LENGTH = 1024;

    public static void main(String[] args) throws Exception {
        char[] buffer = new char[MAX_TITLE_LENGTH * 2];
        GetWindowTextW(GetForegroundWindow(), buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window title: " + Native.toString(buffer));

        PointerByReference pointer = new PointerByReference();
        GetWindowThreadProcessId(GetForegroundWindow(), pointer);
        Pointer process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pointer.getValue());
        GetModuleBaseNameW(process, null, buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window process: " + Native.toString(buffer));
    }

    static class Psapi {
        static { Native.register("psapi"); }
        public static native int GetModuleBaseNameW(Pointer hProcess, Pointer hmodule, char[] lpBaseName, int size);
    }

    static class Kernel32 {
        static { Native.register("kernel32"); }
        public static int PROCESS_QUERY_INFORMATION = 0x0400;
        public static int PROCESS_VM_READ = 0x0010;
        public static native int GetLastError();
        public static native Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer);
    }

    static class User32DLL {
        static { Native.register("user32"); }
        public static native int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref);
        public static native HWND GetForegroundWindow();
        public static native int GetWindowTextW(HWND hWnd, char[] lpString, int nMaxCount);
    }
}
 61
Author: Garrett Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-10 13:33:22

Ten kod działa z JNA 4.0

import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;

// see http://java-native-access.github.io/jna/4.0/javadoc/

public class EnumerateWindows {
    private static final int MAX_TITLE_LENGTH = 1024;

    public static void main(String[] args) throws Exception {
        char[] buffer = new char[MAX_TITLE_LENGTH * 2];
        HWND hwnd = User32.INSTANCE.GetForegroundWindow();
        User32.INSTANCE.GetWindowText(hwnd, buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window title: " + Native.toString(buffer));
        RECT rect = new RECT();
        User32.INSTANCE.GetWindowRect(hwnd, rect);
        System.out.println("rect = " + rect);
    }
 }
 11
Author: John Henckel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-30 16:22:21