java—是否可以将jna keyhook应用于特定进程?

b1zrtrql  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(212)

我的代码是监听键盘键和打印控制台中的键代码。

import com.sun.jna.Pointer;
import com.sun.jna.platform.DesktopWindow;
import com.sun.jna.platform.WindowUtils;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.ptr.IntByReference;

import java.util.List;

public class KeyHook {
    private static volatile boolean quit;
    private static WinUser.HHOOK hhk;
    private static WinUser.LowLevelKeyboardProc keyboardHook;
    private static DesktopWindow myWindow;

    public static void main(String[] args) {
        List<DesktopWindow> listWindow = WindowUtils.getAllWindows(true);
        listWindow.forEach(desktopWindow -> {
            if (desktopWindow.getTitle().equals("My Window Title")) {
                myWindow = desktopWindow;
                System.out.println(myWindow.getTitle() + myWindow.getLocAndSize());
            }
        });

        //Descriptor - a unique number of My Window instance
        WinDef.HWND hwnd = myWindow.getHWND();

        //Native pointer representation for this object, getValue() returns Process ID
        final IntByReference pid = new IntByReference();

        // Thread ID that created the My Window window
        int myWindowThreadProcessId = User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid);
        final User32 lib = User32.INSTANCE;
        WinDef.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
        keyboardHook = new WinUser.LowLevelKeyboardProc() {
            @Override
            public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinUser.KBDLLHOOKSTRUCT info) {
                if (nCode >= 0) {
                    switch (wParam.intValue()) {
                        case WinUser.WM_KEYUP:
                        case WinUser.WM_KEYDOWN:
                        case WinUser.WM_SYSKEYUP:
                        case WinUser.WM_SYSKEYDOWN:
                            System.err.println("in callback, key=" + info.vkCode);
                            if (info.vkCode == 81) {
                                quit = true;
                            }
                    }
                }

                Pointer ptr = info.getPointer();
                long peer = Pointer.nativeValue(ptr);
                return lib.CallNextHookEx(hhk, nCode, wParam, new WinDef.LPARAM(peer));
            }
        };
        hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
        System.out.println("Keyboard hook installed, type anywhere, 'q' to quit");
        new Thread() {
            @Override
            public void run() {
                while (!quit) {
                    try {
                        Thread.sleep(10);
                    } catch (Exception e) {
                    }
                }
                System.err.println("unhook and exit");
                lib.UnhookWindowsHookEx(hhk);
                System.exit(0);
            }
        }.start();

        // This bit never returns from GetMessage
        int result;
        WinUser.MSG msg = new WinUser.MSG();
        while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
            if (result == -1) {
                System.err.println("error in get message");
                break;
            } else {
                System.err.println("got message");
                lib.TranslateMessage(msg);
                lib.DispatchMessage(msg);
            }
        }
        lib.UnhookWindowsHookEx(hhk);
    }
}

有没有可能只对特定的第三方非java进程应用密钥钩子?对我来说是 private static DesktopWindow myWindow; 当我试图添加 myWindowThreadProcessId 进入 SetWindowsHookEx() setwindowshookex参数图像
就像那样 hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, myWindowThreadProcessId); 钥匙钩根本不起作用。
也许有人知道是否有可能为一个特定的进程实现一个键钩子?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题