running_process_core/
console_detect.rs1#[derive(Debug, Clone)]
8pub struct ConsoleWindowInfo {
9 pub pid: u32,
10 pub title: String,
11 pub hwnd: u64,
12}
13
14#[cfg(windows)]
18mod imp {
19 use super::ConsoleWindowInfo;
20 use std::collections::HashSet;
21 use std::time::{Duration, Instant};
22
23 use winapi::shared::minwindef::{BOOL, LPARAM, TRUE};
24 use winapi::shared::windef::HWND;
25 use winapi::um::winuser::{
26 EnumWindows, GetWindowTextW, GetWindowThreadProcessId, IsWindowVisible,
27 };
28
29 fn enumerate_visible_windows() -> Vec<ConsoleWindowInfo> {
31 let mut results: Vec<ConsoleWindowInfo> = Vec::new();
32
33 unsafe extern "system" fn enum_callback(hwnd: HWND, lparam: LPARAM) -> BOOL {
34 if IsWindowVisible(hwnd) == 0 {
36 return TRUE; }
38
39 let mut pid: u32 = 0;
41 GetWindowThreadProcessId(hwnd, &mut pid);
42
43 let mut title_buf: [u16; 512] = [0u16; 512];
45 let len = GetWindowTextW(hwnd, title_buf.as_mut_ptr(), title_buf.len() as i32);
46 let title = if len > 0 {
47 String::from_utf16_lossy(&title_buf[..len as usize])
48 } else {
49 String::new()
50 };
51
52 let results = &mut *(lparam as *mut Vec<ConsoleWindowInfo>);
53 results.push(ConsoleWindowInfo {
54 pid,
55 title,
56 hwnd: hwnd as u64,
57 });
58
59 TRUE }
61
62 unsafe {
63 EnumWindows(
64 Some(enum_callback),
65 &mut results as *mut Vec<ConsoleWindowInfo> as LPARAM,
66 );
67 }
68
69 results
70 }
71
72 pub fn monitor_console_windows(duration: Duration) -> Vec<ConsoleWindowInfo> {
78 let baseline: HashSet<u64> = enumerate_visible_windows()
80 .iter()
81 .map(|w| w.hwnd)
82 .collect();
83
84 let mut seen_new: HashSet<u64> = HashSet::new();
85 let mut new_windows: Vec<ConsoleWindowInfo> = Vec::new();
86
87 let start = Instant::now();
88 let poll_interval = Duration::from_millis(50);
89
90 while start.elapsed() < duration {
91 std::thread::sleep(poll_interval);
92
93 for info in enumerate_visible_windows() {
94 if !baseline.contains(&info.hwnd) && seen_new.insert(info.hwnd) {
95 new_windows.push(info);
96 }
97 }
98 }
99
100 new_windows
101 }
102}
103
104#[cfg(windows)]
105pub use imp::monitor_console_windows;
106
107#[cfg(not(windows))]
111pub fn monitor_console_windows(_duration: std::time::Duration) -> Vec<ConsoleWindowInfo> {
112 Vec::new()
113}