Java查找Windows下exe程序的工具栏,并模拟点击功能按钮,实现自己的功能
使用到的jar包
1、jna-5.5.0
2、jna-platform-5.5.0
3、hutool-all-5.0.5
使用到的exe工具
#spy++.exe 用于获取exe程序的各窗口类名
#不同程序自行修改代码
简单逻辑:
1、开机启动XXX.exe,使用User32.instance循环查找工具栏tdxBarControl子类,模拟点击“退出”;
2、第二次启动XXX.exe,使用User32.instance循环查找工具栏tdxBarControl子类,模拟点击“开启服务”;
3、桌面最小化,打开需要打开的第三方软件(如:XXX.exe)
java程序
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.HWND;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.swing.RobotUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.setting.Setting;
public class AutoRunSIP2Service {
private static final Log logger = LogFactory.get();
private static final Robot robot;
static {
try {
robot = new Robot();
} catch (AWTException e) {
throw new UtilException(e);
}
}
public static void main(String[] args) {
// 读取classpath下的config目录下的XXX.setting,不使用变量
Setting setting = new Setting("config.setting");
String appPath = setting.getStr("appPath");
String exeTitle = setting.getStr("exeTitle");
String otherApp = setting.getStr("otherApp");
String otherAppPath = setting.getStr("otherAppPath");
// 初始化程序,并获取工具栏尺寸
WinDef.RECT Bar_RECT = initalizeApp(appPath, exeTitle);
// 获取退出按钮尺寸
int exit_width = (Bar_RECT.right - Bar_RECT.left) * 7 / 8 + Bar_RECT.left;
int exit_height = (Bar_RECT.bottom - Bar_RECT.top) / 2 + Bar_RECT.top;
// 获取开始服务按钮尺寸
int start_width = (Bar_RECT.right - Bar_RECT.left) * 5 / 8 + Bar_RECT.left;
int start_height = (Bar_RECT.bottom - Bar_RECT.top) / 2 + Bar_RECT.top;
// 调用机器人第一次退出程序
RobotUtil.mouseMove(exit_width, exit_height);
RobotUtil.click();
//键盘回车
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
robot.delay(2000);
// 第二次初始化程序,并获取工具栏尺寸
Bar_RECT = initalizeApp(appPath, exeTitle);
// 调用机器人第二次开启服务
RobotUtil.mouseMove(start_width, start_height);
RobotUtil.click();
//显示桌面
robot.keyPress(KeyEvent.VK_WINDOWS);
robot.keyPress(KeyEvent.VK_D);
robot.keyRelease(KeyEvent.VK_WINDOWS);
robot.keyRelease(KeyEvent.VK_D);
//判断是否启动第三方程序
if("true".equals(otherApp)) {
logger.info(DateUtil.now() + "准备启动第三方程序");
robot.delay(2000);
RuntimeUtil.exec(otherAppPath);
}else {
logger.info(DateUtil.now() + "不启动第三方程序");
}
}
private static WinDef.RECT initalizeApp(String appPath, String exeTitle) {
// 获取exeTitle程序句柄
User32 user32 = User32.INSTANCE;
HWND hwnd = user32.FindWindow(null, exeTitle);
if (hwnd == null) {
// 启动程序
RuntimeUtil.exec(appPath);
ThreadUtil.sleep(2000);
}
//重新查找程序句柄
hwnd = user32.FindWindow(null, exeTitle);
if (hwnd == null) {
logger.error(DateUtil.now() + exeTitle + "---程序未运行");
System.exit(0);
}
// 获取工具栏父级句柄
HWND tdxDockControl = user32.FindWindowEx(hwnd, null, "TdxDockControl", null);
if (tdxDockControl == null) {
logger.info(DateUtil.now() + "tdxDockControl 对象获取失败");
System.exit(0);
}
// 获取工具栏句柄
HWND tdxBarControl = user32.FindWindowEx(tdxDockControl, null, "TdxBarControl", null);
if (tdxBarControl == null) {
logger.info(DateUtil.now() + "tdxBarControl 对象获取失败");
System.exit(0);
}
WinDef.RECT Bar_RECT = getRECT(user32, hwnd, tdxBarControl);
return Bar_RECT;
}
private static WinDef.RECT getRECT(User32 user32, HWND hwnd, HWND tdxBarControl) {
// 打开窗口
user32.ShowWindow(tdxBarControl, 9);
// 切换窗口到最前
user32.SetForegroundWindow(tdxBarControl);
// 获取hwnd前台窗口
WinDef.RECT hwnd_RECT = new WinDef.RECT();
user32.GetWindowRect(hwnd, hwnd_RECT);
// 获取bar前台窗口
WinDef.RECT Bar_RECT = new WinDef.RECT();
user32.GetWindowRect(tdxBarControl, Bar_RECT);
return Bar_RECT;
}
}
配置文件
//SIP接口全路径
appPath=C:\sw\SIP2Service.exe
//金盘接口窗口标题
exeTitle=SIP2服务程序
//XXX程序全路径,当otherApp=true时,启动。否则,不启动。
otherApp=true
otherAppPath=C:\sw\xxx\xxx.exe