我真的很难弄明白为什么我不能在java应用程序中使用钩子。。
我创建了一个C++WINAPI窗口。我加载我的“钩子”dll,每次我向应用程序发送假输入时,它都会很好地引发一个标志。
然而,如果我对Java应用程序做同样的操作,它根本不起作用!
我的dll如下所示:
#include <windows.h>
HINSTANCE hInstance = nullptr;
HHOOK MouseHook = {0}; /** Structure for hooking the mouse **/
HHOOK KeyboardHook = {0}; /** Structure for hooking the keyboard **/
LRESULT __stdcall MouseHookProc(int Code, WPARAM wParam, LPARAM lParam)
{
if (Code == HC_ACTION)
{
MSLLHOOKSTRUCT* Info = reinterpret_cast<MSLLHOOKSTRUCT*>(lParam);
if ((Info->flags & LLMHF_INJECTED) == LLMHF_INJECTED)
{
MessageBox(NULL, "DETECTED Mouse", "", 0);
}
}
return CallNextHookEx(MouseHook, Code, wParam, lParam);
}
LRESULT __stdcall KeyboardHookProc(int Code, WPARAM wParam, LPARAM lParam)
{
if (Code == HC_ACTION)
{
KBDLLHOOKSTRUCT* Info = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
if ((Info->flags & LLKHF_INJECTED) == LLKHF_INJECTED)
{
MessageBox(NULL, "DETECTED Keyboard", "", 0);
}
}
return CallNextHookEx(KeyboardHook, Code, wParam, lParam);
}
extern "C" __declspec(dllexport) bool __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
hInstance = hinstDLL;
SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, hInstance, 0);
SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hInstance, 0);
}
break;
case DLL_PROCESS_DETACH:
{
UnhookWindowsHookEx(KeyboardHook);
UnhookWindowsHookEx(MouseHook);
}
break;
}
return true;
}
然后我创建了一个C++WINAPI应用程序
WM_CREATE
块:
case WM_CREATE:
LoadLibrary("JavaHook.dll");
mouse_event(MOUSEEVENTF_LEFTDOWN, 100, 100, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP,100, 100,0,0);
break;
弹出MouseHook的MessageBox。这是预期的行为。
然而,对于Java,我做到了:
public class HookTest {
public static void main(String[] args) {
JFrame frame = new JFrame("Test Window");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
System.loadLibrary("JavaHook");
}
}
然后我在应用程序上使用SendInput,如下所示:
INPUT input;
input.type = INPUT_MOUSE;
input.mi.mouseData = 0;
input.mi.dx = 100 * (65536 / GetSystemMetrics(SM_CXSCREEN)); //x being coord in pixels
input.mi.dy = 100 * (65536 / GetSystemMetrics(SM_CYSCREEN)); //y being coord in pixels
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
SendInput(1, &input, sizeof(input));
什么都没有弹出。我试过使用
mouse_event
和
keybd_event
,仍然没有。我尝试使用Java鼠标监听器和键盘监听器,并伪造事件。。仍然一无所获。。
钩子肯定会加载,因为我可以看到我的鼠标在移动之前有很长的3秒钟的延迟。在加载时也会弹出一个窗口来确认。
然而,我仍然无法理解为什么它在Java应用程序上不起作用。我能让他们工作吗。或者,有没有另一种方法可以更好地从C/C++为Java实现?如果没有,有没有用Java实现的方法?