有的时候需要我们对鼠标和键盘的动作(鼠标的移动,键盘的点击)进行监听,比如按键记录,鼠标坐标记录等。
我们使用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();
- }
- }
上面是一个鼠标监听的日志文件