diff --git a/apps/desktop/src-tauri/src/agent.rs b/apps/desktop/src-tauri/src/agent.rs index 522a976..88fe5cc 100644 --- a/apps/desktop/src-tauri/src/agent.rs +++ b/apps/desktop/src-tauri/src/agent.rs @@ -723,6 +723,39 @@ fn collect_windows_extended() -> serde_json::Value { serde_json::from_str(trimmed).ok() } + fn decode_powershell_text(bytes: &[u8]) -> Option { + if bytes.is_empty() { + return None; + } + if bytes.starts_with(&[0xFF, 0xFE]) { + return decode_utf16_le_to_string(&bytes[2..]); + } + if bytes.len() >= 2 && bytes[1] == 0 { + if let Some(s) = decode_utf16_le_to_string(bytes) { + return Some(s); + } + } + if bytes.contains(&0) { + if let Some(s) = decode_utf16_le_to_string(bytes) { + return Some(s); + } + } + std::str::from_utf8(bytes).map(|s| s.to_string()).ok() + } + + fn decode_utf16_le_to_string(bytes: &[u8]) -> Option { + if bytes.len() % 2 != 0 { + return None; + } + let utf16: Vec = bytes + .chunks_exact(2) + .map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]])) + .collect(); + String::from_utf16(&utf16) + .ok() + .map(|s| s.trim().to_string()) + } + fn encode_ps_script(script: &str) -> String { let mut bytes = Vec::with_capacity(script.len() * 2); for unit in script.encode_utf16() { @@ -749,6 +782,11 @@ fn collect_windows_extended() -> serde_json::Value { .output() .ok()?; if out.stdout.is_empty() { + if cfg!(test) && !out.stderr.is_empty() { + if let Some(err) = decode_powershell_text(&out.stderr) { + eprintln!("[collect_windows_extended] PowerShell stderr for `{cmd}`: {err}"); + } + } return None; } parse_powershell_json(&out.stdout)