有的时候需要我们对鼠标和键盘的动作(鼠标的移动,键盘的点击)进行监听,比如按键记录,鼠标坐标记录等。
我们使用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(); } }
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/10340.html