tonhowtf/omniget · error
UninstallString sem GUID
Error message
UninstallString sem GUID: {} What it means
On Windows, when an app's UninstallString is an msiexec invocation, uninstall() extracts the MSI product GUID by splitting on braces. If no GUID can be extracted (empty result), it throws 'UninstallString sem GUID' with the raw command string. This guards against running msiexec /x with an invalid product code.
Solutions
- Inspect the registry key (HKLM\...\Uninstall) to verify the UninstallString and note the actual product code
- Extract the GUID with a proper regex like \{[0-9A-Fa-f-]{36}\} instead of brace splitting
- Uninstall manually with the real product code: `msiexec /x <GUID> /passive /norestart`
- If the app is not actually MSI-based, treat it as a generic command-line uninstall instead of forcing the msiexec path
Example fix
// before
let guid = cmd.split(['{','}']).nth(1).map(|g| format!("{{{}}}", g)).unwrap_or_default();
// after
let guid = cmd.split(['{','}']).nth(1).map(|g| format!("{{{}}}", g)).unwrap_or_default();
let guid = regex::Regex::new(r"\{[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\}")
.ok().and_then(|re| re.find(cmd)).map(|m| m.as_str().to_string()).unwrap_or(guid); Defensive patterns
Strategy: validation
Validate before calling
fn extract_msi_guid(cmd: &str) -> Option<String> {
let re = regex::Regex::new(r"\{[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\}").ok()?;
re.find(cmd).map(|m| m.as_str().to_string())
} Type guard
fn is_msi_with_guid(uninstall_string: &str) -> bool {
uninstall_string.to_ascii_lowercase().contains("msiexec")
&& uninstall_string.contains('{')
&& uninstall_string.contains('}')
} Try / catch
match uninstall::uninstall(&app).await {
Err(e) if e.to_string().starts_with("UninstallString sem GUID") => {
// fall back to generic command-line uninstall
run_custom_uninstall(&app);
}
other => other,
} Prevention
- Inspect UninstallString in the registry before choosing the msiexec path
- Use a GUID regex instead of brace splitting
- Provide a generic uninstaller fallback for non-standard MSI strings
When it happens
Trigger: The Windows registry UninstallString contains 'msiexec' but splitting the command on '{' and '}' yields no second segment — e.g. 'MsiExec.exe /X{ malformed', a non-GUID product code, or a custom msiexec command line.
Common situations: Vendor-installed registry entries with custom uninstall strings; MSI product codes written without braces; quiet-mode flags interleaved in the string the simple brace-split cannot parse.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/dbd3ea6c80944198.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/uninstall.rs:664
);
run("osascript", &["-e", &script])
.await
.map(|_| "movido para a Lixeira".into())
.map_err(|_| anyhow!("{}", e))
}
}
} else if cfg!(target_os = "windows") {
let cmd = app.key.trim();
let lower = cmd.to_ascii_lowercase();
if lower.contains("msiexec") {
// MsiExec.exe /I{GUID} → /X{GUID} silencioso
let guid = cmd
.split(['{', '}'])
.nth(1)
.map(|g| format!("{{{}}}", g))
.unwrap_or_default();
if guid.is_empty() {
Err(anyhow!("UninstallString sem GUID: {}", cmd))
} else {
run("msiexec", &["/x", &guid, "/passive", "/norestart"])
.await
.map(|_| "desinstalado".into())
}
} else {
run("cmd", &["/C", cmd])
.await
.map(|_| "desinstalador executado".into())
}
} else {
match app.kind.as_str() {
"flatpak" => run(
"flatpak",
&[
"uninstall",
"-y",
"--delete-data",View on GitHub (pinned to 8600b91f42)