From 4d04dc26770cfa8ea379487ab18b7cb36e7797b0 Mon Sep 17 00:00:00 2001 From: Begild Date: Mon, 19 Aug 2024 08:35:11 +0800 Subject: [PATCH] =?UTF-8?q?windows=E8=8E=B7=E5=8F=96=E7=AA=97=E5=8F=A3?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84api=E6=90=9E=E5=AE=9A=E7=AD=89?= =?UTF-8?q?=E5=BE=85=E5=AE=8C=E5=96=84message=E7=9A=84=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=80=BB=E8=BE=91=E3=80=82=201.=20message?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E9=87=8D=E5=A4=8D=E8=AE=BE=E7=BD=AE=E5=A4=9A?= =?UTF-8?q?=E6=AC=A1=EF=BC=8C=E7=9B=B8=E5=90=8C=E7=9A=84message=E5=8F=AA?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=B8=80=E6=AC=A1=202.=20=E9=BC=A0=E6=A0=87?= =?UTF-8?q?=E5=9C=A8L3=E7=A7=BB=E5=87=BA=E5=8E=BB=E5=B0=B1=E5=8F=91?= =?UTF-8?q?=E9=80=81=E5=89=AA=E5=88=87=E6=9D=BF=E6=B6=88=E6=81=AF=E4=B8=8D?= =?UTF-8?q?=E8=A1=8C=EF=BC=8C=E9=9C=80=E8=A6=81=E6=8D=A2=E6=88=90=E7=9B=91?= =?UTF-8?q?=E5=90=ACwindows=E5=89=AA=E5=88=87=E6=9D=BF=EF=BC=8C=E5=8F=AA?= =?UTF-8?q?=E6=9C=89=E5=86=85=E5=AE=B9=E5=8F=98=E5=8A=A8=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E5=80=99=E5=B9=B6=E4=B8=94=E9=BC=A0=E6=A0=87=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E5=88=B0=E7=AA=97=E5=8F=A3=E5=A4=96=E9=9D=A2=E5=86=8D=E5=8F=91?= =?UTF-8?q?=E9=80=81=EF=BC=8C=E9=81=BF=E5=85=8D=E5=8F=91=E9=80=81=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E7=9A=84=E6=B6=88=E6=81=AF=E3=80=82=203.=20=E9=BC=A0?= =?UTF-8?q?=E6=A0=87=E5=9C=A8L0=E5=8F=AA=E8=A6=81=E5=89=8D=E5=8F=B0?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E6=97=B6VM=20horizontal=E6=97=B6=E7=A7=BB?= =?UTF-8?q?=E5=87=BA=E7=AA=97=E5=8F=A3=E5=A4=96=E5=B0=B1=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E5=89=AA=E5=88=87=E6=9D=BF=E7=9A=84=E5=90=8C=E6=AD=A5=E3=80=82?= =?UTF-8?q?=204.=20=E5=8D=95=E4=B8=AA=E6=B6=88=E6=81=AF=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E4=BD=9C=E4=B8=BAmagic=20str=EF=BC=8C?= =?UTF-8?q?=E8=BF=99=E9=83=A8=E5=88=86=E9=9C=80=E8=A6=81=E9=80=82=E9=85=8D?= =?UTF-8?q?=E4=B8=80=E4=B8=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 2 +- src/lib.rs | 58 +++++++++++++++++++++++++---------------- src/sys_res/mod.rs | 64 +++++++++++++++++++++++++--------------------- 3 files changed, 72 insertions(+), 52 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d7025a6..857205d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ select = "0.5" scraper = "0.12" arboard = "3.4.0" -winapi = { version = "0.3.9", features = ["winuser"] } +winapi = { version = "0.3.9", features = ["winuser", "psapi"] } [profile.test] env = { "RUST_LOG" = "debug" } diff --git a/src/lib.rs b/src/lib.rs index ce715ca..ae9b53b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,19 +1,20 @@ use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; -use reqwest::header::{HeaderMap, CONTENT_TYPE, COOKIE}; +use reqwest::header::HeaderMap; use reqwest::{Client, Response}; use scraper::{Html, Selector}; use std::error::Error; use std::io; -use std::ops::Index; use std::time::Duration; -use tokio::sync::{Mutex}; +use tokio::sync::Mutex; use std::sync::Arc; use tokio::{task, time}; -use std::collections::{BTreeMap, VecDeque}; +use std::collections::BTreeMap; extern crate log; pub mod wclip; pub mod sys_res; + +use sys_res::*; pub struct ClipboardSync { user_name: String, password: String, @@ -22,7 +23,7 @@ pub struct ClipboardSync { cookies: String, clip: wclip::Wclip, //last message magic - cache_magic: u8, + cache_magic: String, } const USER_AGENT: &str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42"; @@ -35,11 +36,15 @@ pub struct ClipboardMsgs { pub msgs: Vec, } +// 同步获取消息的线程 async fn msg_sync(ctx:Arc>){ let mut ctx = ctx.lock().await; loop{ let _ = ctx.update_msg().await; time::sleep(Duration::new(10, 0)).await; + let prog_name = get_foredround_window_name(); + if prog_name == "VMware Horizon Client"{ + } } } pub async fn start_msg_sync(ctx:Arc>) -> Result, Box>{ @@ -48,8 +53,10 @@ pub async fn start_msg_sync(ctx:Arc>) -> Result{ - Msg(&'a str), - Sub((u8, u8, u8, &'a str)), + // magic str, message context + Msg((String, &'a str)), + //index of message pack, total message pack number, magic str, message context + Sub((u8, u8, String, &'a str)), } impl ClipboardSync { @@ -61,7 +68,7 @@ impl ClipboardSync { ip: ip.to_string(), cookies: "".to_string(), clip: wclip::Wclip::new(), - cache_magic: 0xff, + cache_magic: "0xff".to_string(), } } @@ -163,6 +170,8 @@ impl ClipboardSync { self.msg2clip(&resp).await; Ok(()) } + + //解析可能存在的消息数据 fn parse_msg<'a>(msg: &'a str) -> Msg { //x|x|x| -> index|total|magic| let head = &msg[0..7]; @@ -177,17 +186,21 @@ impl ClipboardSync { }).map(|x|x.as_bytes()[0] - b'!').collect::>(); if check.len() != 3 { - return Msg::Msg(msg) + //TODO: get magic + return Msg::Msg(("maigic".to_string(), msg)) } - return Msg::Sub((check[0], check[1], check[2], body)); + return Msg::Sub((check[0], check[1], check[2].to_string(), body)); } + + //将message解析并放置到剪切板上 pub async fn msg2clip(&mut self, html: &str) { // log::info!("html: {}", html); let document = Html::parse_document(html); + // 所有剪切板的数据都是在code这个html lable上的 let selector = Selector::parse("code").unwrap(); let mut msg_map = BTreeMap::new(); - let mut magic_ref = 0xff; + let mut magic_ref = "0xff".to_string(); let mut is_first = true; for element in document.select(&selector).into_iter() { //let text = element.text().collect::>().concat(); @@ -195,20 +208,21 @@ impl ClipboardSync { log::info!("Found: [{}]", text); let msg = ClipboardSync::parse_msg(text.as_str()); match msg { + //一整个消息。直接复制到剪切板即可 Msg::Msg(msg) => { - if magic_ref == 0xff { - self.clip.set(&msg); - break; + if magic_ref == "0xff" { + self.clip.set(msg.1); + break;//处理完毕。直接退出 } }, - Msg::Sub((index, total, magic, _body)) => { - magic_ref = if magic_ref == 0xff {magic} else {magic_ref}; - if magic_ref != magic { // other message ignore - if is_first { - break; + Msg::Sub((index, total, magic, body)) => { + if magic_ref == "0xff" { + magic_ref = magic; + } else { + if magic_ref != magic { // other message ignore + is_first = false; + continue } - is_first = false; - continue } if msg_map.len() == 0 && ( self.cache_magic == magic_ref // message is repeated ignore it @@ -217,7 +231,7 @@ impl ClipboardSync { break; } // same msg pack, append to list - msg_map.insert(index, text); + msg_map.insert(index, body.to_string()); if msg_map.len() as u8 == total { let msg = msg_map.into_iter().map(|(_key, v)| v).collect::(); self.cache_magic = magic_ref; // save for next msg diff --git a/src/sys_res/mod.rs b/src/sys_res/mod.rs index c25fdbd..b80401a 100755 --- a/src/sys_res/mod.rs +++ b/src/sys_res/mod.rs @@ -1,21 +1,19 @@ extern crate winapi; extern crate log; -use std::ptr::null_mut; +use std::path::Path; use winapi::um::winuser::{ - GetCursorPos, GetSystemMetrics, SM_CXSCREEN, SM_CYSCREEN, - FindWindowA, GetWindowRect + GetCursorPos, GetSystemMetrics, SM_CXSCREEN, SM_CYSCREEN,GetWindowRect }; use winapi::shared::windef::{ POINT, RECT, }; -use winapi::um::winuser::{GetForegroundWindow, GetWindowTextW, GetClassNameW, GetWindowThreadProcessId}; -use std::ptr; -use std::ffi::{OsString, CString}; +use winapi::um::winuser::{GetForegroundWindow, GetWindowThreadProcessId}; +use std::ffi::OsString; use std::os::windows::ffi::OsStringExt; -use winapi::um::processthreadsapi::{OpenProcess, GetProcessImageFileNameA}; +use winapi::um::processthreadsapi::OpenProcess; use winapi::um::winnt::PROCESS_QUERY_INFORMATION; - +use winapi::um::psapi::GetProcessImageFileNameW; pub fn screen_size() -> (i32, i32) { unsafe { @@ -35,69 +33,77 @@ pub fn cursor_pos() -> (i32, i32) { } } -pub fn get_window_rect() -> Option<(i32, i32, i32, i32)> { +pub fn get_foredround_window_rect() -> Option<(i32, i32, i32, i32)> { unsafe { let h = GetForegroundWindow(); let mut rect: RECT = std::mem::zeroed(); if GetWindowRect(h, &mut rect) != 0 { + println!("GetWindowRect: {:?}", rect); Some((rect.left, rect.top, rect.right, rect.bottom)) } else { + println!("cant get foregtound window rect"); None } } } -pub fn get_foredround_window_name() { +pub fn get_foredround_window_name() -> String { + let mut name = OsString::new(); unsafe { let foreground_window = GetForegroundWindow(); - // let mut process_id = 0; - // GetWindowThreadProcessId(foreground_window, &mut process_id); + let mut process_id = 0; + GetWindowThreadProcessId(foreground_window, &mut process_id); // let mut process_name: [u16; 1024] = [0; 1024]; // GetWindowTextW(foreground_window, process_name.as_mut_ptr(), 1024); - let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid); + let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, process_id); if process_handle.is_null() { - return None; + panic!("Cant open foreground process with {}!", process_id) } - let mut image_name = [0u8; 1024]; - let mut image_name_size = image_name.len() as u32; - if GetProcessImageFileNameA(process_handle, image_name.as_mut_ptr() as *mut _, &mut image_name_size) == 0 { - return None; + let mut image_name = [0u16; 1024]; + if GetProcessImageFileNameW(process_handle, image_name.as_mut_ptr() as *mut _, image_name.len() as u32) == 0 { + panic!("Cant Get foreground prog name!") } - - let mut class_name: [u16; 256] = [0; 256]; - GetClassNameW(foreground_window, class_name.as_mut_ptr(), 256); - let mut process_name_str = OsString::from_wide(&process_name); - let mut class_name_str = OsString::from_wide(&class_name); + // let mut class_name: [u16; 256] = [0; 256]; + // GetClassNameW(foreground_window, class_name.as_mut_ptr(), 256); - log::info!("Process Name: {}", process_name_str.to_string_lossy().to_string()); - log::info!("Class Name: {}", class_name_str.to_string_lossy().to_string()); + name = OsString::from_wide(&image_name); + // let mut class_name_str = OsString::from_wide(&class_name); + // log::info!("Class Name: {}", class_name_str.to_string_lossy().to_string()); } + let path = Path::new(&name); + let name = path.file_name().unwrap().to_string_lossy().to_string(); + println!("Current Proc Name: [{}]", name); + name + } #[test] fn test_screen_size() { + // env_logger::init(); let (width, height) = screen_size(); assert!(width > 0); assert!(height > 0); } #[test] -fn test_get_window_rect() { - let (x, y, width, height) = get_window_rect().unwrap(); - assert!(x >= 0); - assert!(y >= 0); +fn test_get_foredround_window_rect() { + // env_logger::init(); + let (x, y, width, height) = get_foredround_window_rect().unwrap(); + // assert!(x >= 0); + // assert!(y >= 0); assert!(width > 0); assert!(height > 0); } #[test] fn test_cursor_pos() { + // env_logger::init(); let (x, y) = cursor_pos(); assert!(x >= 0); assert!(y >= 0);