Thr*_*ror 5 automation window rust
目前,我正在为一位客户工作,他希望自动化其会计应用程序中的某些操作。
我在一个箱子中搜索了这个,但没有找到任何东西,无法读取另一个窗口的屏幕,并发布一些消息,例如按键交互或单击交互。
有人知道 Rust 中有一个与另一个窗口交互的箱子吗?我需要交互:窗口屏幕阅读,发布一些关键消息,并向该窗口发布一些点击消息。
有各种包可以让您甚至以跨平台的方式模拟用户输入(例如鼠标和键盘输入):
以及用于截图的板条箱,例如
除此之外,还有一个autopilot可以让您两者兼得。
autopilot以下是使用和捕获主窗口屏幕的示例image(用于实际存储图像):
use image::{GenericImageView, png::PNGEncoder};
fn main() {
let bitmap = autopilot::bitmap::capture_screen().expect("Failed to capture main screen.");
let mut buf = Vec::new();
let encoder = PNGEncoder::new(
&mut buf
);
encoder
.encode(
&bitmap.image.as_rgb8().unwrap(),
bitmap.image.width(),
bitmap.image.height(),
image::ColorType::RGB(8),
)
.expect("Failed to encode png.");
std::fs::write("test.png", buf).expect("Failed to write screenshot to disk.");
}
Run Code Online (Sandbox Code Playgroud)
这是鼠标输入的示例(将光标移动一个圆圈):
use image::{GenericImageView, png::PNGEncoder};
fn main() {
let bitmap = autopilot::bitmap::capture_screen().expect("Failed to capture main screen.");
let mut buf = Vec::new();
let encoder = PNGEncoder::new(
&mut buf
);
encoder
.encode(
&bitmap.image.as_rgb8().unwrap(),
bitmap.image.width(),
bitmap.image.height(),
image::ColorType::RGB(8),
)
.expect("Failed to encode png.");
std::fs::write("test.png", buf).expect("Failed to write screenshot to disk.");
}
Run Code Online (Sandbox Code Playgroud)
如果您只想捕获窗口区域,可以通过截取完整桌面的屏幕截图,然后仅将其裁剪到窗口来实现。在 Windows 上,您可以使用 获取某个窗口的窗口矩形GetWindowRect。下面是使用 ID 或名称获取窗口矩形的代码片段。
以下是如何仅捕获包含给定窗口的屏幕特定部分的示例(仅适用于窗口,并且窗口必须在屏幕上完全可见):
const MARGIN: f64 = 10.0;
const MILLIS: u64 = 10;
struct Center {
x: f64,
y: f64,
}
fn main() {
circle_mouse().expect("Unable to move mouse");
}
fn circle_mouse() -> Result<(), autopilot::mouse::MouseError> {
let screen_size = autopilot::screen::size();
let scoped_height = screen_size.height / 2.0 - MARGIN;
let scoped_width = screen_size.width / 2.0 - MARGIN;
let scoped_radius;
if scoped_height > scoped_width {
scoped_radius = scoped_width;
}
else {
scoped_radius = scoped_height;
}
let center = Center { x: scoped_width, y: scoped_height };
for i in 0..360 {
let x = (i as f64 / 180.0 * std::f64::consts::PI).cos() * scoped_radius;
let y = (i as f64 / 180.0 * std::f64::consts::PI).sin() * scoped_radius;
autopilot::mouse::move_to(autopilot::geometry::Point::new(
center.x + x as f64,
center.y + y as f64,
))?;
std::thread::sleep(std::time::Duration::from_millis(MILLIS));
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
该示例具有以下依赖项:
autopilot = "0.4.0"
windows-sys = { version = "0.36.1", features = ["Win32_Foundation", "Win32_UI_WindowsAndMessaging"] }
Run Code Online (Sandbox Code Playgroud)
请注意,这确实包括您可能不想要的不可见窗口边框。您可以使用DwmGetWindowAttribute以下方法来校正视觉偏移:
use autopilot::geometry::{Point, Rect, Size};
use std::{ffi::OsString, iter::once, os::windows::prelude::OsStrExt, ptr::null};
use windows_sys::Win32::{
Foundation::{HWND, RECT},
UI::WindowsAndMessaging::{FindWindowW, GetWindowRect},
};
fn main() {
// The title of the window (is shown when hovering over the window in the taskbar):
let window_name = OsString::from("autopilot");
let window_name: Vec<u16> = window_name
.as_os_str()
.encode_wide()
.chain(once(0))
.collect();
let id: HWND = unsafe { FindWindowW(null(), window_name.as_ptr()) };
let mut rect = RECT {
left: 0,
top: 0,
right: 0,
bottom: 0,
};
if id != 0 && unsafe { GetWindowRect(id, &mut rect) } != 0 {
/* println!(
"HWND: {}\nLocation: {} {}\nSize: {} {}",
id,
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top
); */
let bitmap = autopilot::bitmap::capture_screen_portion(Rect::new(
Point::new(rect.left as f64, rect.top as f64),
Size::new(
(rect.right - rect.left) as f64,
(rect.bottom - rect.top) as f64,
),
))
.expect("Failed to capture screen portion.");
bitmap
.image
.save("screen_portion.png")
.expect("Failed to write image to disk.");
}
}
Run Code Online (Sandbox Code Playgroud)
使用这些依赖项
autopilot = "0.4.0"
windows-sys = { version = "0.36.1", features = ["Win32_Foundation", "Win32_Graphics_Dwm", "Win32_UI_WindowsAndMessaging"] }
Run Code Online (Sandbox Code Playgroud)
是的,您也可以在 Rust 中使用WinAPIPostMessageW中的函数。这是一个简单的示例,其中包含链接示例的基本思想:
autopilot = "0.4.0"
windows-sys = { version = "0.36.1", features = ["Win32_Foundation", "Win32_UI_WindowsAndMessaging"] }
Run Code Online (Sandbox Code Playgroud)
这取决于
windows-sys = { version = "0.36.1", features = ["Win32_Foundation", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_WindowsAndMessaging"] }
Run Code Online (Sandbox Code Playgroud)
如果您想检测屏幕上的某些 UI 元素并获取它们的位置,您可能需要使用模式匹配/计算机视觉自行实现这一点,使用类似的东西opencv并使用事先截取的屏幕截图作为输入。
| 归档时间: |
|
| 查看次数: |
1896 次 |
| 最近记录: |