diff --git a/apps/desktop/src-tauri/src/agent.rs b/apps/desktop/src-tauri/src/agent.rs index 88fe5cc..dc2126b 100644 --- a/apps/desktop/src-tauri/src/agent.rs +++ b/apps/desktop/src-tauri/src/agent.rs @@ -699,28 +699,22 @@ fn collect_windows_extended() -> serde_json::Value { } fn parse_powershell_json(bytes: &[u8]) -> Option { - if bytes.is_empty() { + let text = decode_powershell_text(bytes)?; + if text.is_empty() { return None; } - if bytes.starts_with(&[0xFF, 0xFE]) { - return parse_utf16_le_bytes(&bytes[2..]); - } - if bytes.len() >= 2 && bytes[1] == 0 { - if let Some(val) = parse_utf16_le_bytes(bytes) { - return Some(val); + match serde_json::from_str::(&text) { + Ok(value) => Some(value), + Err(err) => { + if cfg!(test) { + let preview = text.chars().take(512).collect::(); + eprintln!( + "[collect_windows_extended] falha ao interpretar JSON: {err}; amostra: {preview}" + ); + } + None } } - if bytes.contains(&0) { - if let Some(val) = parse_utf16_le_bytes(bytes) { - return Some(val); - } - } - let text = std::str::from_utf8(bytes).ok()?; - let trimmed = text.trim(); - if trimmed.is_empty() { - return None; - } - serde_json::from_str(trimmed).ok() } fn decode_powershell_text(bytes: &[u8]) -> Option { @@ -740,7 +734,12 @@ fn collect_windows_extended() -> serde_json::Value { return Some(s); } } - std::str::from_utf8(bytes).map(|s| s.to_string()).ok() + let text = std::str::from_utf8(bytes).ok()?.trim().to_string(); + if text.is_empty() { + None + } else { + Some(text) + } } fn decode_utf16_le_to_string(bytes: &[u8]) -> Option { @@ -751,9 +750,13 @@ fn collect_windows_extended() -> serde_json::Value { .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()) + let text = String::from_utf16(&utf16).ok()?; + let trimmed = text.trim(); + if trimmed.is_empty() { + None + } else { + Some(trimmed.to_string()) + } } fn encode_ps_script(script: &str) -> String { @@ -781,15 +784,23 @@ fn collect_windows_extended() -> serde_json::Value { .arg(encoded) .output() .ok()?; - if out.stdout.is_empty() { - if cfg!(test) && !out.stderr.is_empty() { + let stdout_text = decode_powershell_text(&out.stdout); + if cfg!(test) { + if let Some(ref txt) = stdout_text { + let preview = txt.chars().take(512).collect::(); + eprintln!("[collect_windows_extended] stdout `{cmd}` => {preview}"); + } else { + eprintln!("[collect_windows_extended] stdout `{cmd}` => "); + } + if !out.stderr.is_empty() { if let Some(err) = decode_powershell_text(&out.stderr) { - eprintln!("[collect_windows_extended] PowerShell stderr for `{cmd}`: {err}"); + eprintln!("[collect_windows_extended] stderr `{cmd}` => {err}"); + } else { + eprintln!("[collect_windows_extended] stderr `{cmd}` => "); } } - return None; } - parse_powershell_json(&out.stdout) + stdout_text.and_then(|text| serde_json::from_str::(&text).ok()) } let software = ps(r#"@(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'; Get-ItemProperty 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*') | Where-Object { $_.DisplayName } | Select-Object DisplayName, DisplayVersion, Publisher"#)