这个其实不光微信,QQ也是可以的,想一下平时如果想刷屏群聊,聊天不爽了想骂回去,惹女朋友生气了想不停的道歉,或者每天定时问候一下,这些如果都要自己手动操作也太麻烦了吧,还不如写一个程序解决了呢。(等等,我哪里来的女朋友)
好了,下面直接上代码了:
先导入maven依赖,主要是用来实现微信窗口置顶的jar包:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.5.0</version>
</dependency>
接下来就是编码了:
/**
* @author jinghuaixin
* @date 2020/05/14
*/
public class RobotUtil {
private static Robot robot;
private static Clipboard clip;
private static Toolkit kit;
public static void main(String[] args) throws AWTException {
// 微信窗口置顶成功
if (topWeChat()) {
// 初始化
init();
// 指定需要发送消息的联系人/群组
queryItemForSendMessage("文件传输助手"); // 微信昵称/群名
// 发送字符串消息
// for (int i = 0; i < 3; i++) { // 循环发送
sendStrMessage("你好吗");
// }
// 发送图片消息
sendImgMessage("exceltest.jpg"); // 表情包的路径
}
}
/**
* 置顶微信窗口
*
* @return
*/
public static boolean topWeChat() {
boolean flag = true;
WinDef.HWND hwnd = User32.INSTANCE.FindWindow(null, "微信");
if (hwnd == null) {
flag = false;
System.out.println("not running");
} else {
User32.INSTANCE.ShowWindow(hwnd, 9);
User32.INSTANCE.SetForegroundWindow(hwnd); // bring to front
}
return flag;
}
/**
* 初始化全局变量
*
*/
private static void init() {
try {
robot = new Robot();
} catch (AWTException e) {
robot = null;
e.printStackTrace();
}
kit = Toolkit.getDefaultToolkit();
clip = kit.getSystemClipboard();
}
/**
* 查找需要发送消息的人员/群组
*
* @param userName
*/
public static void queryItemForSendMessage(String itemName) {
if (robot == null) {
return;
}
robot.delay(2000); // 给窗口置顶预留时间
// 模拟在微信上进行Ctrl+F进行查询操作
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_CONTROL); // 是否Ctrl键
// 将字符串放到剪切板内,相当于做了一次复制操作
Transferable tText = new StringSelection(itemName);
clip.setContents(tText, null);
// 以下两行按下了ctrl+v,完成粘贴功能
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);// 释放ctrl按键,像ctrl,退格键,删除键这样的功能性按键,在按下后一定要释放,不然会出问题。crtl如果按住没有释放,在按其他字母按键是,敲出来的回事ctrl的快捷键。
robot.keyPress(KeyEvent.VK_ENTER); // 按下enter键进行查询
robot.delay(2000); // 预留查询时间
robot.keyPress(KeyEvent.VK_ENTER); // 再次按下enter键进行选中
robot.delay(1000);
}
/**
* 发送字符串消息
*
* @param message
*/
public static void sendStrMessage(String message) {
if (robot == null) {
return;
}
// 将字符串放到剪切板内,相当于做了一次复制操作
Transferable tText = new StringSelection(message);
clip.setContents(tText, null);
// 以下两行按下了ctrl+v,完成粘贴功能
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);// 释放ctrl按键,像ctrl,退格键,删除键这样的功能性按键,在按下后一定要释放,不然会出问题。crtl如果按住没有释放,在按其他字母按键是,敲出来的回事ctrl的快捷键。
robot.keyPress(KeyEvent.VK_ENTER); // 按下enter键进行消息发送
robot.delay(1000);
}
/**
* 发送字符串消息
*
* @param message
*/
public static void sendImgMessage(String imgPath) {
if (robot == null) {
return;
}
// 将字符串放到剪切板内,相当于做了一次复制操作
Transferable tImg = new ImageSelection(kit.getImage(imgPath));
clip.setContents(tImg, null);
// 以下两行按下了ctrl+v,完成粘贴功能
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);// 释放ctrl按键,像ctrl,退格键,删除键这样的功能性按键,在按下后一定要释放,不然会出问题。crtl如果按住没有释放,在按其他字母按键是,敲出来的回事ctrl的快捷键。
robot.keyPress(KeyEvent.VK_ENTER); // 按下enter键进行消息发送
robot.delay(1000);
}
}
/**
* 自定义Transferable实现类实现图片复制到剪切板
*
* @date 2020/05/14
*/
class ImageSelection implements Transferable {
private Image image;
public ImageSelection(Image image) {
this.image = image;
}
// Returns supported flavors
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] {DataFlavor.imageFlavor};
}
// Returns true if flavor is supported
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.imageFlavor.equals(flavor);
}
// Returns image
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
if (!DataFlavor.imageFlavor.equals(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
return image;
}
}
代码也没有什么好说的,是借助java的Robot类模拟人对键盘进行的操作,思路就是:
1.如果微信打开了则进行微信窗口置顶
2.模拟Ctrl+F进入搜索,输入搜索内容,按Enter键搜索,再次按下Enter键选中搜索出来的人员/群组
3.发送消息
具体操作,代码里面注释已经写得很清楚了,如果想要刷屏,加个循环,循环调用发送消息函数就可以了。
运行程序就可以看到,消息发送成功了: