Handle PowerShell UTF-16 output and show Windows edition
This commit is contained in:
parent
459bd53693
commit
0aa474c88e
2 changed files with 49 additions and 15 deletions
|
|
@ -680,25 +680,45 @@ fn collect_windows_extended() -> serde_json::Value {
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||||
|
|
||||||
|
fn parse_utf16_le_bytes(bytes: &[u8]) -> Option<serde_json::Value> {
|
||||||
|
if bytes.len() % 2 != 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let utf16: Vec<u16> = bytes
|
||||||
|
.chunks_exact(2)
|
||||||
|
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
|
||||||
|
.collect();
|
||||||
|
let text = String::from_utf16(&utf16).ok()?;
|
||||||
|
let trimmed = text.trim();
|
||||||
|
if trimmed.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
serde_json::from_str(trimmed).ok()
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_powershell_json(bytes: &[u8]) -> Option<serde_json::Value> {
|
fn parse_powershell_json(bytes: &[u8]) -> Option<serde_json::Value> {
|
||||||
if bytes.is_empty() {
|
if bytes.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if bytes.starts_with(&[0xFF, 0xFE]) {
|
if bytes.starts_with(&[0xFF, 0xFE]) {
|
||||||
// PowerShell usa UTF-16LE por padrão no Windows; converter para UTF-8.
|
return parse_utf16_le_bytes(&bytes[2..]);
|
||||||
let data = &bytes[2..];
|
}
|
||||||
if data.len() % 2 != 0 {
|
if bytes.len() >= 2 && bytes[1] == 0 {
|
||||||
|
if let Some(val) = parse_utf16_le_bytes(bytes) {
|
||||||
|
return Some(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
return None;
|
||||||
}
|
}
|
||||||
let utf16: Vec<u16> = data
|
serde_json::from_str(trimmed).ok()
|
||||||
.chunks_exact(2)
|
|
||||||
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
|
|
||||||
.collect();
|
|
||||||
let text = String::from_utf16(&utf16).ok()?;
|
|
||||||
serde_json::from_str(&text).ok()
|
|
||||||
} else {
|
|
||||||
serde_json::from_slice(bytes).ok()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ps(cmd: &str) -> Option<serde_json::Value> {
|
fn ps(cmd: &str) -> Option<serde_json::Value> {
|
||||||
|
|
|
||||||
|
|
@ -1092,6 +1092,20 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
const osNameDisplay = useMemo(() => {
|
||||||
|
const base = machine?.osName?.trim()
|
||||||
|
const edition = windowsEditionLabel?.trim()
|
||||||
|
if (edition) {
|
||||||
|
if (base && edition.toLowerCase().includes(base.toLowerCase())) {
|
||||||
|
return edition
|
||||||
|
}
|
||||||
|
if (base) {
|
||||||
|
return `${base} ${edition}`.replace(/\s+/g, " ").trim()
|
||||||
|
}
|
||||||
|
return edition
|
||||||
|
}
|
||||||
|
return base ?? ""
|
||||||
|
}, [machine?.osName, windowsEditionLabel])
|
||||||
const linuxLsblk = linuxExt?.lsblk ?? []
|
const linuxLsblk = linuxExt?.lsblk ?? []
|
||||||
const linuxSmartEntries = linuxExt?.smart ?? []
|
const linuxSmartEntries = linuxExt?.smart ?? []
|
||||||
const normalizedHardwareGpus = Array.isArray(hardware?.gpus)
|
const normalizedHardwareGpus = Array.isArray(hardware?.gpus)
|
||||||
|
|
@ -1176,7 +1190,7 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
||||||
|
|
||||||
const summaryChips = useMemo(() => {
|
const summaryChips = useMemo(() => {
|
||||||
const chips: Array<{ key: string; label: string; value: string; icon: ReactNode; tone?: "warning" | "muted" }> = []
|
const chips: Array<{ key: string; label: string; value: string; icon: ReactNode; tone?: "warning" | "muted" }> = []
|
||||||
const osName = machine?.osName ?? "Sistema desconhecido"
|
const osName = osNameDisplay || "Sistema desconhecido"
|
||||||
const osVersion = machine?.osVersion ?? windowsVersionLabel ?? ""
|
const osVersion = machine?.osVersion ?? windowsVersionLabel ?? ""
|
||||||
chips.push({
|
chips.push({
|
||||||
key: "os",
|
key: "os",
|
||||||
|
|
@ -1227,7 +1241,7 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return chips
|
return chips
|
||||||
}, [machine?.osName, machine?.osVersion, machine?.architecture, windowsVersionLabel, windowsBuildLabel, windowsActivationStatus, primaryGpu, collaborator?.email, collaborator?.name, personaLabel])
|
}, [osNameDisplay, machine?.osVersion, machine?.architecture, windowsVersionLabel, windowsBuildLabel, windowsActivationStatus, primaryGpu, collaborator?.email, collaborator?.name, personaLabel, machine?.osName])
|
||||||
|
|
||||||
const companyName = (() => {
|
const companyName = (() => {
|
||||||
if (!companies || !machine?.companySlug) return machine?.companySlug ?? null
|
if (!companies || !machine?.companySlug) return machine?.companySlug ?? null
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue