【发布时间】:2019-06-11 11:34:51
【问题描述】:
背景:
我将击键发送到我隐藏的程序(文本编辑器),然后发送 F7 键,然后发送四个文本键(一种密码)。我正在使用 JNA 库和 Win32API 的 SendMessage 函数发送消息,不能使用 sendInput() 因为我需要发送到特定的窗口句柄。
代码:
private static void sendInputToWindow(WinDef.HWND editorWindowHandle, char[] password) throws InterruptedException {
User32.INSTANCE.ShowWindow(editorWindowHandle, WinUser.SW_HIDE);
User32.INSTANCE.SetForegroundWindow(editorWindowHandle);
User32.INSTANCE.SetFocus(editorWindowHandle);
//F7 KEY SENT
WinDef.WPARAM wparam = new WinDef.WPARAM(F7_VIRTUAL_KEY);
WinDef.LPARAM lparam = new WinDef.LPARAM(0);
log.debug("SENDING F7");
User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_KEYDOWN, wparam, lparam);
Thread.sleep(1000);
log.debug("SENDING PASSWORD");
// PASSWORD SENT
User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_CHAR, new WinDef.WPARAM(password[0]), lparam);
User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_CHAR, new WinDef.WPARAM(password[1]), lparam);
User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_CHAR, new WinDef.WPARAM(password[2]), lparam);
User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_CHAR, new WinDef.WPARAM(password[3]), lparam);
Thread.sleep(500);
log.debug("SENDING ENTER");
// ENTER KEY SENT
User32.INSTANCE.SendMessage(editorWindowHandle, WinUser.WM_KEYDOWN, new WinDef.WPARAM(ENTER_KEY), lparam);
}
问题:
当我通过 SendMessage 发送击键时,经过一段时间或随机发送(我不知道是什么导致了这里的问题),但有时它根本不发送击键!
所以这是一个命中或未命中的情况,大多数情况下它会发送击键,而其他时候则不会。我想知道是否有更好的方法将击键发送到隐藏窗口?或者我在这里做错了什么。
谢谢。
【问题讨论】:
-
没有单一的机制可以做到这一点。
SendInput是受支持的伪造输入方式。其他任何事情都只是黑客行为。当然,您不能指望直接发送WM_CHAR消息。究竟什么对你有用取决于目标(又名受害者)窗口。正如我们在这里看到的大量输入伪造问题中经常出现的情况一样,重要的细节被省略了。例如,如果这只是一个 Win32 编辑控件,您可以使用WM_SETTEXT。但我们实际上并不知道这个控件到底是什么。 -
如果您确实想自动化 UI,可以使用 UI Automation。
-
@IInspectable 是否可以通过 Java 库(如在 JNA 中)使用,还是我必须为此使用 JNI?
-
UI 自动化作为一组 COM 对象公开。 COM 与语言无关。我会惊讶地发现,没有用于 COM 的 JNA 包装器,甚至没有预构建的 UI 自动化库(如 this 之一)。
-
LPCWSTR Target_window_Name = TEXT("print.txt - Notepad"); HWND hWindowHandle = FindWindow(NULL, Target_window_Name); LRESULT 结果 = SendMessage(hWindowHandle, WM_SETFOCUS, 0, 0); std::cout