From 85dae4377f2e538f36fd1b374bcc42a8f5ce0e9b Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Thu, 23 Apr 2026 16:54:46 +0200 Subject: [PATCH] fix(cloud-files): AppliesTo-Syntax fuer Kontextmenue reparieren Alter AppliesTo-Wert hatte: - verdoppelte Backslashes (Windows AQS will einfache) - einen verirrten Schluss-Backslash in der Quote, was die Query aufgebrochen hat Neu: - Saubere AQS-Syntax: System.ItemPathDisplay:~< "C:\\..." mit einfachen Backslashes (winreg schreibt REG_SZ 1:1) - Registrierung unter AllFilesystemObjects statt *, damit auch Ordner den Menueeintrag erhalten - Default-Wert (MUIVerb zusaetzlich) gesetzt, weil manche Windows- Versionen den Default fuer den Anzeigename nutzen - uninstall entfernt beide Registry-Stellen (alte und neue) Hinweis fuer Windows 11: klassische Shell-Verben stehen standard- maessig nur unter "Weitere Optionen anzeigen" (Shift+F10). Fuer das Haupt-Menue braeuchte man IExplorerCommand via COM-Extension. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/cloud_files/shell_integration.rs | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/clients/desktop/src-tauri/src/cloud_files/shell_integration.rs b/clients/desktop/src-tauri/src/cloud_files/shell_integration.rs index abbec92..9fbc78a 100644 --- a/clients/desktop/src-tauri/src/cloud_files/shell_integration.rs +++ b/clients/desktop/src-tauri/src/cloud_files/shell_integration.rs @@ -120,22 +120,27 @@ fn install_context_menu(mount_point: &Path) -> Result<(), String> { .map_err(|e| format!("current_exe: {e}"))? .to_string_lossy() .into_owned(); - let mount_str = mount_point.to_string_lossy(); - // AppliesTo filtert die Verben auf Pfade, die unter dem Mount liegen. - // Syntax: "System.ItemPathDisplay:~< \"C:\\Users\\..\\Mini-Cloud\\\"" - let applies_to = format!( - "System.ItemPathDisplay:~< \"{}\\\"", - mount_str.replace('\\', "\\\\") - ); + // Trailing Backslash wegstrippen, dann eine saubere AQS-Query bauen. + // Registry-Werte sind normale Strings; Backslashes bleiben einfach. + let mount_clean = mount_point + .to_string_lossy() + .trim_end_matches('\\') + .to_string(); + // AppliesTo: nur Dateien, deren Pfad mit dem Mount-Ordner beginnt. + let applies_to = format!("System.ItemPathDisplay:~< \"{}\"", mount_clean); for (verb, label, flag) in [ ("MiniCloudPin", "Immer offline verfuegbar", "--pin"), ("MiniCloudUnpin", "Speicher freigeben", "--unpin"), ] { - let key_path = format!("Software\\Classes\\*\\shell\\{}", verb); + // Unter AllFilesystemObjects statt * - das greift auch fuer + // Ordner und vermeidet Konflikte mit Dateityp-spezifischen Verben. + let key_path = format!("Software\\Classes\\AllFilesystemObjects\\shell\\{}", verb); let (k, _) = hkcu .create_subkey(&key_path) .map_err(|e| format!("verb {verb}: {e}"))?; + k.set_value("", &label.to_string()) + .map_err(|e| format!("default: {e}"))?; k.set_value("MUIVerb", &label.to_string()) .map_err(|e| format!("MUIVerb: {e}"))?; k.set_value("AppliesTo", &applies_to) @@ -155,7 +160,12 @@ fn install_context_menu(mount_point: &Path) -> Result<(), String> { fn uninstall_context_menu() { let hkcu = RegKey::predef(HKEY_CURRENT_USER); for verb in ["MiniCloudPin", "MiniCloudUnpin"] { + // alte (falsche) Stelle ebenfalls aufraeumen let _ = hkcu.delete_subkey_all(format!("Software\\Classes\\*\\shell\\{}", verb)); + let _ = hkcu.delete_subkey_all(format!( + "Software\\Classes\\AllFilesystemObjects\\shell\\{}", + verb + )); } }