use windows::{ core::*, Win32::Foundation::{HWND, LPARAM}, Win32::UI::WindowsAndMessaging::{ EnumWindows, GetForegroundWindow, GetWindowTextW, GetWindowTextLengthW, GetWindowThreadProcessId, IsWindowVisible, }, Win32::System::Threading::{OpenProcess, QueryFullProcessImageNameW, PROCESS_QUERY_INFORMATION, PROCESS_NAME_WIN32}, }; use serde::Serialize; use serde_json; #[derive(Serialize)] struct WindowInfo { hwnd: String, title: String, pid: u32, process_name: String, is_active: bool, } #[derive(Serialize)] struct WindowList { active_window: Option, all_windows: Vec, } fn main() -> std::result::Result<(), Box> { unsafe { // 获取当前激活窗口 let active_hwnd = GetForegroundWindow(); let active_info = if !active_hwnd.is_invalid() { Some(get_window_info(active_hwnd)) } else { None }; // 获取所有窗口 let mut all_windows: Vec = Vec::new(); EnumWindows( Some(enum_windows_callback), LPARAM(&mut all_windows as *mut Vec as isize), )?; let result = WindowList { active_window: active_info, all_windows, }; let json = serde_json::to_string_pretty(&result) .map_err(|e| Box::new(e) as Box)?; println!("{}", json); Ok(()) } } unsafe fn get_window_info(hwnd: HWND) -> WindowInfo { // 获取窗口标题 let len = GetWindowTextLengthW(hwnd); let title = if len > 0 { let mut buffer = vec![0u16; len as usize + 1]; let actual_len = GetWindowTextW(hwnd, &mut buffer); if actual_len > 0 { String::from_utf16_lossy(&buffer[..actual_len as usize]) } else { String::new() } } else { String::new() }; // 获取进程ID let mut pid: u32 = 0; GetWindowThreadProcessId(hwnd, Some(&mut pid)); // 获取进程名称 let process_name = get_process_name(pid).unwrap_or_else(|_| String::from("Unknown")); // 检查是否为激活窗口 let is_active = hwnd == GetForegroundWindow(); WindowInfo { hwnd: format!("{:?}", hwnd.0), title, pid, process_name, is_active, } } unsafe fn get_process_name(pid: u32) -> Result { let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid)?; let mut buffer = vec![0u16; 1024]; let mut size = buffer.len() as u32; QueryFullProcessImageNameW(process_handle, PROCESS_NAME_WIN32, PWSTR(buffer.as_mut_ptr()), &mut size)?; let path = String::from_utf16_lossy(&buffer[..size as usize]); // 提取文件名 let process_name = path.split('\\').last().unwrap_or(&path).to_string(); Ok(process_name) } unsafe extern "system" fn enum_windows_callback( hwnd: HWND, lparam: LPARAM, ) -> windows::Win32::Foundation::BOOL { if IsWindowVisible(hwnd).as_bool() { let len = GetWindowTextLengthW(hwnd); if len > 0 { let windows = &mut *(lparam.0 as *mut Vec); windows.push(get_window_info(hwnd)); } } windows::Win32::Foundation::TRUE }