返回顶部

收藏

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

更多

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

我们使用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);  
        }  

    }  

最后是获取进程信息的代码```java 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();  
            }  
        }  
    }

}
开启上述线程的类```java
    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();    
        }    

    }    

标签:java

收藏

0人收藏

支持

0

反对

0

发表评论