#[derive(Debug)]
pub struct DebugBrowser {
pub pid: u32,
pub name: String,
pub debug_port: Option<u16>,
}
pub fn find_debug_browser() -> anyhow::Result<Vec<DebugBrowser>> {
unsafe { scan_processes() }
}
unsafe fn scan_processes() -> anyhow::Result<Vec<DebugBrowser>> {
use windows::Win32::System::Diagnostics::ToolHelp::*;
let snap = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) }?;
let mut entry = PROCESSENTRY32W::default();
entry.dwSize = std::mem::size_of::<PROCESSENTRY32W>() as u32;
let mut found = Vec::new();
if unsafe { Process32FirstW(snap, &mut entry) }.is_ok() {
loop {
let pos = entry
.szExeFile
.iter()
.position(|&c| c == 0)
.unwrap_or(entry.szExeFile.len());
let name = String::from_utf16_lossy(&entry.szExeFile[..pos]);
let lower = name.to_lowercase();
if is_chromium_process(&lower) {
found.push(DebugBrowser {
pid: entry.th32ProcessID,
name,
debug_port: None,
});
}
if unsafe { Process32NextW(snap, &mut entry) }.is_err() {
break;
}
}
}
let _ = unsafe { windows::Win32::Foundation::CloseHandle(snap) };
Ok(found)
}
fn is_chromium_process(name: &str) -> bool {
const BROWSERS: &[&str] = &[
"chrome.exe",
"msedge.exe",
"brave.exe",
"vivaldi.exe",
"chromium.exe",
"opera.exe",
];
BROWSERS.iter().any(|browser| name.ends_with(browser))
}