java实现鼠标和键盘动作后台监听

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

有的时候需要我们对鼠标和键盘的动作(鼠标的移动,键盘的点击)进行监听,比如按键记录,鼠标坐标记录等。

我们使用JNA来实现以上的操作

 tips:JNA类库使用一个很小的本地类库sub 动态的调用本地代码。程序员只需要使用一个特定的java接口描述一下将要调用的本地代码的方法的结构和一些基本属性。这样就省了为了适配多个平台而大量的配置和编译代码。因为调用的都是JNA提供的公用jar 包中的接口。

首先我们实现监听鼠标的代码如下

    package getInfo;  
      
    import java.io.BufferedWriter;  
    import java.io.File;  
    import java.io.FileWriter;  
    import java.io.IOException;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  
      
    import com.sun.jna.Structure;  
    import com.sun.jna.examples.win32.Kernel32;  
    import com.sun.jna.examples.win32.User32;  
    import com.sun.jna.examples.win32.User32.HHOOK;  
    import com.sun.jna.examples.win32.User32.MSG;  
    import com.sun.jna.examples.win32.W32API.HMODULE;  
    import com.sun.jna.examples.win32.W32API.LRESULT;  
    import com.sun.jna.examples.win32.W32API.WPARAM;  
    import com.sun.jna.examples.win32.User32.HOOKPROC;  
      
    public class MouseHook implements Runnable{  
          
        public static final int WM_MOUSEMOVE = 512;  
        private static HHOOK hhk;  
        private static LowLevelMouseProc mouseHook;  
        final static User32 lib = User32.INSTANCE;  
        private boolean [] on_off=null;  
      
        public MouseHook(boolean [] on_off){  
            this.on_off = on_off;  
        }  
      
        public interface LowLevelMouseProc extends HOOKPROC {  
            LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);  
        }  
      
        public static class MOUSEHOOKSTRUCT extends Structure {  
            public static class ByReference extends MOUSEHOOKSTRUCT implements  
            Structure.ByReference {  
            };  
            public User32.POINT pt;  
            public int wHitTestCode;  
            public User32.ULONG_PTR dwExtraInfo;  
        }  
      
        public void run() {  
            HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);  
            mouseHook = new LowLevelMouseProc() {  
                public LRESULT callback(int nCode, WPARAM wParam,  
                        MOUSEHOOKSTRUCT info) {  
                    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");  
                    SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                    String fileName=df1.format(new Date());  
                    String time=df2.format(new Date());  
                    BufferedWriter bw1=null;  
                    BufferedWriter bw2=null;  
                    try {  
                        bw1=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Mouse.txt"),true));  
                        bw2=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Common.txt"),true));  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                    if (on_off[0] == false) {  
                        System.exit(0);  
                    }  
                    if (nCode >= 0) {  
                        switch (wParam.intValue()) {  
                        case MouseHook.WM_MOUSEMOVE:  
                            try {  
                                bw1.write(time+"  ####  "+"x=" + info.pt.x  
                                        + " y=" + info.pt.y+"\r\n");  
                                bw2.write(time+"  ####  "+"x=" + info.pt.x  
                                        + " y=" + info.pt.y+"\r\n");  
                                bw1.flush();  
                                bw2.flush();  
                            } catch (IOException e) {  
                                e.printStackTrace();  
                            }  
                        }  
                    }  
                    return lib  
                    .CallNextHookEx(hhk, nCode, wParam, info.getPointer());  
                }  
            };  
            hhk = lib.SetWindowsHookEx(User32.WH_MOUSE_LL, mouseHook, hMod, 0);  
            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);  
        }  
    }  

能够在鼠标移动的时候输出鼠标的坐标位置

接下来是监听键盘的代码

    package getInfo;  
      
    import java.io.BufferedWriter;  
    import java.io.File;  
    import java.io.FileWriter;  
    import java.io.IOException;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  
      
    import com.sun.jna.examples.win32.Kernel32;  
    import com.sun.jna.examples.win32.User32;  
    import com.sun.jna.examples.win32.User32.HHOOK;  
    import com.sun.jna.examples.win32.User32.KBDLLHOOKSTRUCT;  
    import com.sun.jna.examples.win32.User32.LowLevelKeyboardProc;  
    import com.sun.jna.examples.win32.User32.MSG;  
    import com.sun.jna.examples.win32.W32API.HMODULE;  
    import com.sun.jna.examples.win32.W32API.LRESULT;  
    import com.sun.jna.examples.win32.W32API.WPARAM;  
      
      
    public class KeyboardHook implements Runnable{  
      
        private static HHOOK hhk;  
        private static LowLevelKeyboardProc keyboardHook;  
        final static User32 lib = User32.INSTANCE;  
        private boolean [] on_off=null;  
      
        public KeyboardHook(boolean [] on_off){  
            this.on_off = on_off;  
        }  
      
        public void run() {  
      
            HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);  
            keyboardHook = new LowLevelKeyboardProc() {  
                public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {  
                    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");  
                    SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                    String fileName=df1.format(new Date());  
                    String time=df2.format(new Date());  
                    BufferedWriter bw1=null;  
                    BufferedWriter bw2=null;  
                    try {  
                        bw1=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Keyboard.txt"),true));  
                        bw2=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Common.txt"),true));  
                      
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                    if (on_off[0] == false) {  
                        System.exit(0);  
                    }  
                    try {  
                        bw1.write(time+"  ####  "+info.vkCode+"\r\n");  
                        bw2.write(time+"  ####  "+info.vkCode+"\r\n");  
                        bw1.flush();  
                        bw2.flush();  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                    return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());  
                }  
            };  
            hhk = lib.SetWindowsHookEx(User32.WH_KEYBOARD_LL, keyboardHook, hMod, 0);  
            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);  
        }  
      
    }  

最后是获取进程信息的代码
    package getInfo;  
      
    import java.io.BufferedReader;  
    import java.io.BufferedWriter;  
    import java.io.File;  
    import java.io.FileWriter;  
    import java.io.IOException;  
    import java.io.InputStreamReader;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  
      
    public class ProcessInfo implements Runnable{  
      
        private boolean [] on_off=null;  
      
        public ProcessInfo(boolean [] on_off){  
            this.on_off = on_off;  
        }  
      
        public void run() {  
            BufferedReader input = null;  
            Process process = null;  
            BufferedWriter bw=null;  
            SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");  
            SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
            String fileName=null;  
            String time=null;  
            try {  
                while(on_off[0]){  
                    fileName=df1.format(new Date());  
                    time=df2.format(new Date());  
                    bw=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_ProcessInfo.txt"),true));  
                    Thread.sleep(60000);  
                    process = Runtime.getRuntime().exec("cmd.exe   /c   tasklist");  
                    input =new BufferedReader(  
                            new InputStreamReader(process.getInputStream()));  
                    String line = " ";  
                    int i=0;  
                    input.readLine();  
                    input.readLine();  
                    input.readLine();  
                    while ((line = input.readLine()) != null) {  
                        bw.write(time+"  ####  "+line+"\r\n");  
                        bw.flush();  
                        i++;  
                    }  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            } finally{  
                try {  
                    bw.close();  
                    input.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
      
    }  

开启上述线程的类
    package getInfo;  
      
    import java.awt.AWTException;    
    import java.awt.Image;    
    import java.awt.MenuItem;    
    import java.awt.PopupMenu;    
    import java.awt.SystemTray;    
    import java.awt.Toolkit;    
    import java.awt.TrayIcon;    
    import java.awt.event.ActionEvent;    
    import java.awt.event.ActionListener;    
      
    public class Monitor  {    
      
        public Monitor()  {    
            boolean [] on_off={true};  
            new Thread(new ProcessInfo(on_off)).start();  
            new Thread(new KeyboardHook(on_off)).start();  
            new Thread(new MouseHook(on_off)).start();  
            final TrayIcon trayIcon;    
      
            if (SystemTray.isSupported()) {    
      
                SystemTray tray = SystemTray.getSystemTray();    
                Image image = Toolkit.getDefaultToolkit().getImage(".//lib//monitor.png");    
      
                ActionListener exitListener = new ActionListener() {    
                    public void actionPerformed(ActionEvent e) {    
                        System.out.println("Exiting...");    
                        System.exit(0);    
                    }  
                };    
      
                PopupMenu popup = new PopupMenu();    
                MenuItem defaultItem = new MenuItem("Exit");    
                defaultItem.addActionListener(exitListener);    
                popup.add(defaultItem);    
      
                trayIcon = new TrayIcon(image, "monitor", popup);    
      
                ActionListener actionListener = new ActionListener() {    
                    public void actionPerformed(ActionEvent e) {    
                        trayIcon.displayMessage("Action Event",     
                                "An Action Event Has Been Peformed!",    
                                TrayIcon.MessageType.INFO);    
                    }    
                };    
      
                trayIcon.setImageAutoSize(true);    
                trayIcon.addActionListener(actionListener);    
      
                try {    
                    tray.add(trayIcon);    
                } catch (AWTException e1) {    
                    e1.printStackTrace();    
                }    
      
            }   
        }  
          
        public static void main(String[] args)  {    
            new Monitor();    
        }    
      
    }