feat(windows): implement explorer shell integration, auto drive allocation, auto-open, and system tray icon

This commit is contained in:
2026-09-08 10:04:24 +02:00
parent 1c8a860184
commit 38df3d3845
6 changed files with 561 additions and 23 deletions
+53 -4
View File
@@ -41,9 +41,9 @@ enum Commands {
#[arg(short, long)]
path: PathBuf,
/// Laufwerksbuchstabe (z. B. 'S' oder 'S:')
/// Laufwerksbuchstabe (z. B. 'S' oder 'S:', optional; wählt standardmäßig automatisch das nächste freie Laufwerk)
#[arg(short, long)]
drive: String,
drive: Option<String>,
/// Optionaler TCP-Port für den lokalen WebDAV-Server (Standard: 8443)
#[arg(long)]
@@ -52,6 +52,14 @@ enum Commands {
/// Optionaler 24-Wort Notfall-Wiederherstellungsschlüssel (umgeht Passwortabfrage)
#[arg(long)]
recovery_key: Option<String>,
/// Öffnet das Netzlaufwerk nach dem Mounten nicht automatisch im Windows Explorer
#[arg(long, default_value_t = false)]
no_open: bool,
/// Deaktiviert das Windows System-Tray Icon während des Mounts
#[arg(long, default_value_t = false)]
no_tray: bool,
},
/// Trennt ein eingebundenes Netzlaufwerk manuell
@@ -115,6 +123,12 @@ enum Commands {
#[arg(long, default_value_t = true)]
full: bool,
},
/// Registriert .sanctum Containerdateien im Windows Explorer (Doppelklick & Kontextmenü, keine Adminrechte)
Register,
/// Entfernt die .sanctum Explorer-Integration aus der Benutzer-Registry
Unregister,
}
fn parse_drive_letter(s: &str) -> Result<char> {
@@ -465,8 +479,21 @@ async fn run() -> Result<()> {
drive,
port,
recovery_key,
no_open,
no_tray,
} => {
let drive_char = parse_drive_letter(&drive)?;
let drive_char = match drive {
Some(ref d) => parse_drive_letter(d)?,
None => {
let auto_drive = sanctum::windows::find_next_available_drive()?;
println!(
" {} Kein Laufwerksbuchstabe angegeben. Wähle automatisch freien Buchstaben {}:",
ui::cyan(""),
auto_drive
);
auto_drive
}
};
let auth = if let Some(key) = recovery_key {
ContainerAuth::RecoveryKey(key)
} else {
@@ -479,7 +506,9 @@ async fn run() -> Result<()> {
ContainerAuth::Password(password)
};
mount_container(&path, drive_char, port, auth).await?;
let open_explorer = !no_open;
let enable_tray = !no_tray;
mount_container(&path, drive_char, port, auth, open_explorer, enable_tray).await?;
}
Commands::Unmount { drive } => {
let drive_char = parse_drive_letter(&drive)?;
@@ -509,6 +538,26 @@ async fn run() -> Result<()> {
Commands::Verify { path, full } => {
handle_verify(&path, full)?;
}
Commands::Register => {
println!("┌─────────────────────────────────────────────────────────────┐");
println!("│ Sanctum — Windows Explorer Integration einrichten │");
println!("└─────────────────────────────────────────────────────────────┘");
println!();
sanctum::windows::register_explorer_integration()?;
println!(" {} .sanctum-Dateien wurden erfolgreich im Windows Explorer verknüpft!", ui::green(""));
println!(" • Doppelklick: Öffnet und bindet den Container direkt als Laufwerk ein");
println!(" • Rechtsklick: Bietet Optionen für Integritätsprüfung (FSCK) und Header-Backup");
println!();
}
Commands::Unregister => {
println!("┌─────────────────────────────────────────────────────────────┐");
println!("│ Sanctum — Windows Explorer Integration entfernen │");
println!("└─────────────────────────────────────────────────────────────┘");
println!();
sanctum::windows::unregister_explorer_integration()?;
println!(" {} .sanctum Dateiverknüpfungen wurden aus der Registry entfernt.", ui::green(""));
println!();
}
}
Ok(())