diff --git a/CHANGELOG.md b/CHANGELOG.md index b4c507d..9745e5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,10 @@ und dieses Projekt folgt den Richtlinien von [Semantic Versioning](https://semve - `LEGAL.md`: Rechtliche Leitlinien, US EAR § 742.15(b) & EU Dual-Use Exportkontroll-Klassifizierung, DSGVO Art. 25 Zero-Data-Erklärung und Haftungsausschluss nach § 521 BGB. - `THIRD_PARTY_LICENSES.md`: Lückenloses Lizenzaudit aller 231 Abhängigkeiten (100% permissive Lizenzen, 0% Copyleft) zur strikten Compliance mit Apache-2.0 Section 4. - Aufnahme von `LEGAL.md` und `THIRD_PARTY_LICENSES.md` in das offizielle Release-Distributionsarchiv (`package-release.ps1`). +- **Statisches Linux Single-Binary (`x86_64-unknown-linux-musl`)**: + - 100% statisch gelinktes Linux-Binary ohne GLIBC-Abhängigkeiten via Zig-Cross-Toolchain. + - Neues Linux-Distributionsarchiv `sanctum-v0.4.0-linux-x86_64.tar.gz` inklusive Dokumentation und Prüfsummen. + - Native Freedesktop `.desktop`-Datei und MIME-Type-Integration (`application/x-sanctum`) via `sanctum register`. - **OpSec & Disaster Recovery UX**: - `QUICKSTART.md`: Druckbare 24-Wörter BIP-39 Notfallkarte zur sicheren analogen Verwahrung des Notfallschlüssels (Air-Gapped Vault Paper Backup). diff --git a/Cargo.toml b/Cargo.toml index 0e2d932..445da5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,8 @@ dyn-clone = "1.0" lz4_flex = "0.11" bip39 = { version = "2.2", features = ["zeroize"] } hex = "0.4" + +[target.'cfg(windows)'.dependencies] tray-item = "0.10" [profile.release] diff --git a/INSTALL.md b/INSTALL.md index e300cef..9be1d46 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -50,6 +50,25 @@ Winget entpackt das portable Binary automatisch in das Benutzer-Anwendungsverzei --- +## 🐧 4. Installation unter Linux (x86_64) + +Sanctum wird für Linux als **100 % statisches Single-Binary** (`x86_64-unknown-linux-musl`) ohne jegliche GLIBC- oder Bibliotheksabhängigkeiten bereitgestellt. Es läuft direkt auf Ubuntu, Debian, Alpine, Arch, Fedora und weiteren Distributionen: + +1. Lade das Linux-Release herunter und installiere es: + ```bash + curl -LO https://gitea.pansi.eu/harald/sanctum/releases/download/v0.4.0/sanctum-v0.4.0-linux-x86_64.tar.gz + tar -xzf sanctum-v0.4.0-linux-x86_64.tar.gz + chmod +x sanctum + sudo install -m 755 sanctum /usr/local/bin/sanctum + ``` +2. *(Optional)* Freedesktop-Integration einrichten (Doppelklick in GNOME / KDE / Thunar): + ```bash + sanctum register + ``` + *Richtet die `.desktop`-Datei und den MIME-Typ `application/x-sanctum` im Userland (`~/.local/share`) ein.* + +--- + ## 🔄 Updates * **Scoop:** diff --git a/README.md b/README.md index 6a6c514..43e22e8 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,8 @@ powershell -ExecutionPolicy Bypass -File .\scripts\package-release.ps1 ``` Erzeugt: -- `dist/sanctum-v0.4.0-windows-x86_64.zip` +- `dist/sanctum-v0.4.0-windows-x86_64.zip` (Windows x86_64 ZIP) +- `dist/sanctum-v0.4.0-linux-x86_64.tar.gz` (Linux x86_64 musl static TAR.GZ via `package-release-linux.ps1`) - `dist/SHA256SUMS.txt` --- diff --git a/scripts/package-release-linux.ps1 b/scripts/package-release-linux.ps1 new file mode 100644 index 0000000..2d002fa --- /dev/null +++ b/scripts/package-release-linux.ps1 @@ -0,0 +1,119 @@ +param ( + [switch]$SkipBuild = $false +) + +$ErrorActionPreference = "Stop" + +# Repository-Wurzelverzeichnis ermitteln +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +Set-Location $ProjectRoot + +# Toolchain-Pfade sicherstellen (Zig + Cargo Bin) +$ZigDir = "C:\Users\pansih\AppData\Local\Microsoft\WinGet\Packages\zig.zig_Microsoft.Winget.Source_8wekyb3d8bbwe\zig-x86_64-windows-0.16.0" +$env:PATH = "$ZigDir;C:\Users\pansih\.cargo\bin;C:\Windows\System32;" + $env:PATH + +# Version aus Cargo.toml auslesen +$CargoToml = Get-Content (Join-Path $ProjectRoot "Cargo.toml") -Raw +if ($CargoToml -match 'version\s*=\s*"([^"]+)"') { + $Version = $matches[1] +} else { + Write-Error "Konnte Versionsnummer nicht aus Cargo.toml ermitteln." + exit 1 +} + +Write-Host "============================================================" -ForegroundColor Cyan +Write-Host " Sanctum Linux Release Packaging v$Version (x86_64 musl)" -ForegroundColor Cyan +Write-Host "============================================================" -ForegroundColor Cyan + +# 1. Linux Release-Binary bauen +$Target = "x86_64-unknown-linux-musl" +$BinaryPath = Join-Path $ProjectRoot "target\$Target\release\sanctum" + +if (-not $SkipBuild -or -not (Test-Path $BinaryPath)) { + Write-Host "`n[1/3] Kompiliere statisches Linux-Binary via cargo-zigbuild..." -ForegroundColor Yellow + cargo-zigbuild.exe zigbuild --target $Target --release + if ($LASTEXITCODE -ne 0) { + Write-Error "Linux-Build fehlgeschlagen!" + exit $LASTEXITCODE + } + Write-Host "[OK] Linux-Binary erfolgreich gebaut." -ForegroundColor Green +} else { + Write-Host "`n[1/3] Build uebersprungen (-SkipBuild)." -ForegroundColor DarkYellow +} + +# 2. Release-Verzeichnisstruktur vorbereiten +Write-Host "`n[2/3] Erstelle Linux-Distributionspaket..." -ForegroundColor Yellow + +$DistDir = Join-Path $ProjectRoot "dist" +if (-not (Test-Path $DistDir)) { + New-Item -ItemType Directory -Path $DistDir -Force | Out-Null +} + +$PackageName = "sanctum-v$Version-linux-x86_64" +$StagingDir = Join-Path $DistDir $PackageName +$TarGzFile = Join-Path $DistDir "$PackageName.tar.gz" + +if (Test-Path $StagingDir) { + Remove-Item $StagingDir -Recurse -Force +} +New-Item -ItemType Directory -Path $StagingDir -Force | Out-Null + +# Dateien kopieren +Copy-Item $BinaryPath -Destination (Join-Path $StagingDir "sanctum") -Force +Copy-Item (Join-Path $ProjectRoot "README.md") -Destination $StagingDir -Force +Copy-Item (Join-Path $ProjectRoot "LICENSE") -Destination $StagingDir -Force +Copy-Item (Join-Path $ProjectRoot "CHANGELOG.md") -Destination $StagingDir -Force +Copy-Item (Join-Path $ProjectRoot "INSTALL.md") -Destination $StagingDir -Force +Copy-Item (Join-Path $ProjectRoot "QUICKSTART.md") -Destination $StagingDir -Force +Copy-Item (Join-Path $ProjectRoot "LEGAL.md") -Destination $StagingDir -Force +Copy-Item (Join-Path $ProjectRoot "THIRD_PARTY_LICENSES.md") -Destination $StagingDir -Force + +# .tar.gz Archiv erstellen mit Windows nativem bsdtar +if (Test-Path $TarGzFile) { + Remove-Item $TarGzFile -Force +} + +tar.exe -czf $TarGzFile -C $DistDir $PackageName +if ($LASTEXITCODE -ne 0) { + Write-Error "Fehler beim Erstellen des tar.gz-Archivs!" + exit $LASTEXITCODE +} + +# Staging-Verzeichnis bereinigen +Remove-Item $StagingDir -Recurse -Force + +Write-Host "[OK] Archiv erstellt: $TarGzFile" -ForegroundColor Green + +# 3. SHA-256 Pruefsummen berechnen und aktualisieren +Write-Host "`n[3/3] Aktualisiere SHA-256 Pruefsummen..." -ForegroundColor Yellow + +$ChecksumFile = Join-Path $DistDir "SHA256SUMS.txt" +$TarHash = (Get-FileHash -Path $TarGzFile -Algorithm SHA256).Hash.ToLower() +$ElfHash = (Get-FileHash -Path $BinaryPath -Algorithm SHA256).Hash.ToLower() + +# Existierende Pruefsummen lesen und um Linux-Assets ergaenzen/aktualisieren +$ExistingLines = if (Test-Path $ChecksumFile) { + Get-Content $ChecksumFile | Where-Object { $_ -notmatch "$PackageName\.tar\.gz" -and $_ -notmatch "\s+sanctum$" } +} else { + @() +} + +$AllLines = @() +$AllLines += $ExistingLines +$AllLines += "$TarHash $PackageName.tar.gz" +$AllLines += "$ElfHash sanctum" + +$AllLines | Set-Content -Path $ChecksumFile -Encoding utf8 + +$TarSizeMB = [math]::Round((Get-Item $TarGzFile).Length / 1MB, 2) +$ElfSizeMB = [math]::Round((Get-Item $BinaryPath).Length / 1MB, 2) + +Write-Host "`n============================================================" -ForegroundColor Green +Write-Host " Sanctum Linux Release v$Version erfolgreich gepackt!" -ForegroundColor Green +Write-Host "============================================================" -ForegroundColor Green +Write-Host " Archiv: $TarGzFile ($TarSizeMB MB)" +Write-Host " TAR SHA-256: $TarHash" +Write-Host " ELF SHA-256: $ElfHash" +Write-Host " Checksum-File: $ChecksumFile" +Write-Host "`nBereit fuer Gitea Release." diff --git a/scripts/publish-release.ps1 b/scripts/publish-release.ps1 index 7cae953..75dd183 100644 --- a/scripts/publish-release.ps1 +++ b/scripts/publish-release.ps1 @@ -108,42 +108,56 @@ if (-not $Release) { $UploadUrl = "$GiteaUrl/api/v1/repos/$Owner/$Repo/releases/$($Release.id)/assets" $AuthHeader = "Authorization: token $Token" -# ZIP Asset hochladen -Write-Host "Lade sanctum-$TagName-windows-x86_64.zip hoch..." -ForegroundColor Cyan -$ZipPathNorm = $ZipFile.Replace('\', '/') -$ZipUrl = "${UploadUrl}?name=sanctum-$TagName-windows-x86_64.zip" -$ZipResult = & curl.exe -sS -X POST $ZipUrl -H $AuthHeader -F "attachment=@$ZipPathNorm" -if ($LASTEXITCODE -ne 0) { - Write-Error "Upload von sanctum-$TagName-windows-x86_64.zip fehlgeschlagen: $ZipResult" - exit 1 -} -Write-Host "[OK] sanctum-$TagName-windows-x86_64.zip hochgeladen." -ForegroundColor Green +# Hilfsfunktion zum sauberen Hochladen/Ersetzen von Assets +function Upload-ReleaseAsset { + param ( + [string]$FilePath, + [string]$AssetName + ) -# SHA256SUMS.txt hochladen -Write-Host "Lade SHA256SUMS.txt hoch..." -ForegroundColor Cyan -$SumPathNorm = $ChecksumFile.Replace('\', '/') -$SumUrl = "${UploadUrl}?name=SHA256SUMS.txt" -$SumResult = & curl.exe -sS -X POST $SumUrl -H $AuthHeader -F "attachment=@$SumPathNorm" -if ($LASTEXITCODE -ne 0) { - Write-Error "Upload von SHA256SUMS.txt fehlgeschlagen: $SumResult" - exit 1 -} -Write-Host "[OK] SHA256SUMS.txt hochgeladen." -ForegroundColor Green + if (-not (Test-Path $FilePath)) { + return + } -# Standalone EXE hochladen -$ExeFile = Join-Path $ProjectRoot "target\release\sanctum.exe" -if (Test-Path $ExeFile) { - Write-Host "Lade sanctum.exe hoch..." -ForegroundColor Cyan - $ExePathNorm = $ExeFile.Replace('\', '/') - $ExeUrl = "${UploadUrl}?name=sanctum.exe" - $ExeResult = & curl.exe -sS -X POST $ExeUrl -H $AuthHeader -F "attachment=@$ExePathNorm" + Write-Host "Lade $AssetName hoch..." -ForegroundColor Cyan + + # Vorhandenes Asset mit gleichem Namen ermitteln und ggf. loeschen + $ExistingAssets = try { + Invoke-RestMethod -Uri $UploadUrl -Headers $Headers -Method Get + } catch { + @() + } + $Duplicate = $ExistingAssets | Where-Object { $_.name -eq $AssetName } + if ($Duplicate) { + Write-Host " [i] Ersetze existierendes Asset '$AssetName' (ID: $($Duplicate.id))..." -ForegroundColor DarkYellow + $DeleteUrl = "$GiteaUrl/api/v1/repos/$Owner/$Repo/releases/$($Release.id)/assets/$($Duplicate.id)" + Invoke-RestMethod -Uri $DeleteUrl -Headers $Headers -Method Delete | Out-Null + } + + $PathNorm = $FilePath.Replace('\', '/') + $TargetUrl = "${UploadUrl}?name=$AssetName" + $Result = & curl.exe -sS -X POST $TargetUrl -H $AuthHeader -F "attachment=@$PathNorm" if ($LASTEXITCODE -ne 0) { - Write-Error "Upload von sanctum.exe fehlgeschlagen: $ExeResult" + Write-Error "Upload von $AssetName fehlgeschlagen: $Result" exit 1 } - Write-Host "[OK] sanctum.exe hochgeladen." -ForegroundColor Green + Write-Host "[OK] $AssetName erfolgreich hochgeladen." -ForegroundColor Green } +# Windows-Assets hochladen +Upload-ReleaseAsset -FilePath $ZipFile -AssetName "sanctum-$TagName-windows-x86_64.zip" +$ExeFile = Join-Path $ProjectRoot "target\release\sanctum.exe" +Upload-ReleaseAsset -FilePath $ExeFile -AssetName "sanctum.exe" + +# Linux-Assets hochladen +$LinuxTar = Join-Path $DistDir "sanctum-$TagName-linux-x86_64.tar.gz" +Upload-ReleaseAsset -FilePath $LinuxTar -AssetName "sanctum-$TagName-linux-x86_64.tar.gz" +$LinuxElf = Join-Path $ProjectRoot "target\x86_64-unknown-linux-musl\release\sanctum" +Upload-ReleaseAsset -FilePath $LinuxElf -AssetName "sanctum" + +# SHA256SUMS.txt hochladen +Upload-ReleaseAsset -FilePath $ChecksumFile -AssetName "SHA256SUMS.txt" + Write-Host "`n============================================================" -ForegroundColor Green Write-Host " Release $TagName erfolgreich auf Gitea veroeffentlicht!" -ForegroundColor Green diff --git a/src/mount.rs b/src/mount.rs index 2581ee9..6fb51a5 100644 --- a/src/mount.rs +++ b/src/mount.rs @@ -289,7 +289,7 @@ pub async fn mount_container( } // System-Tray Initialisierung - let (tray_shutdown_tx, mut tray_shutdown_rx) = tokio::sync::mpsc::channel::<()>(1); + let (_tray_shutdown_tx, mut tray_shutdown_rx) = tokio::sync::mpsc::channel::<()>(1); #[cfg(windows)] let _tray = if enable_tray { let icon_source = crate::windows::get_default_system_icon() @@ -307,7 +307,7 @@ pub async fn mount_container( let _ = tray.add_menu_item("Im Explorer öffnen", move || { let _ = crate::windows::open_in_explorer(dl); }); - let s_tx = tray_shutdown_tx.clone(); + let s_tx = _tray_shutdown_tx.clone(); let _ = tray.add_menu_item("Trennen & Beenden", move || { let _ = s_tx.blocking_send(()); }); @@ -321,6 +321,8 @@ pub async fn mount_container( } else { None }; + #[cfg(not(windows))] + let _tray: Option<()> = None; // Inaktivitäts-Timer (Auto-Lock) let (idle_shutdown_tx, mut idle_shutdown_rx) = tokio::sync::mpsc::channel::<()>(1); diff --git a/src/windows.rs b/src/windows.rs index 5ef0e00..43db31c 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -1,5 +1,6 @@ use std::process::Command; +#[allow(unused_imports)] use anyhow::{bail, Context, Result}; /// Ermittelt den nächsten verfügbaren Windows-Laufwerksbuchstaben (von 'Z' rückwärts bis 'D'). @@ -130,102 +131,137 @@ pub fn notify_shell_associations_changed() { } } -/// Registriert `.sanctum`-Containerdateien im Windows Explorer für den aktuellen Benutzer (HKCU, 100% Userland, keine Adminrechte). +/// Registriert `.sanctum`-Containerdateien im Windows Explorer für den aktuellen Benutzer bzw. unter Linux via Freedesktop. pub fn register_explorer_integration() -> Result<()> { - let current_exe = std::env::current_exe() - .context("Konnte den Pfad zur aktuellen sanctum.exe nicht ermitteln")?; - let exe_str = current_exe.display().to_string(); + #[cfg(windows)] + { + let current_exe = std::env::current_exe() + .context("Konnte den Pfad zur aktuellen sanctum.exe nicht ermitteln")?; + let exe_str = current_exe.display().to_string(); - let reg_commands = [ - // 1. .sanctum Erweiterung mit ProgID verknüpfen - ( - r"HKCU\Software\Classes\.sanctum", - "", - "Sanctum.Container", - ), - // 2. ProgID Metadaten & Beschreibung - ( - r"HKCU\Software\Classes\Sanctum.Container", - "", - "Sanctum Verschlüsselter Container", - ), - // 3. Icon - ( - r"HKCU\Software\Classes\Sanctum.Container\DefaultIcon", - "", - &format!("\"{exe_str}\",0"), - ), - // 4. Standard-Doppelklick-Aktion: Mount - ( - r"HKCU\Software\Classes\Sanctum.Container\shell\open", - "", - "Als Laufwerk einbinden", - ), - ( - r"HKCU\Software\Classes\Sanctum.Container\shell\open\command", - "", - &format!("\"{exe_str}\" mount --path \"%1\""), - ), - // 5. Kontextmenü-Aktion: Integritätsprüfung - ( - r"HKCU\Software\Classes\Sanctum.Container\shell\verify", - "", - "Integrität prüfen (FSCK)", - ), - ( - r"HKCU\Software\Classes\Sanctum.Container\shell\verify\command", - "", - &format!("\"{exe_str}\" verify --path \"%1\""), - ), - // 6. Kontextmenü-Aktion: Header sichern - ( - r"HKCU\Software\Classes\Sanctum.Container\shell\backup_header", - "", - "Header sichern", - ), - ( - r"HKCU\Software\Classes\Sanctum.Container\shell\backup_header\command", - "", - &format!("\"{exe_str}\" backup-header --path \"%1\""), - ), - ]; + let reg_commands = [ + // 1. .sanctum Erweiterung mit ProgID verknüpfen + ( + r"HKCU\Software\Classes\.sanctum", + "", + "Sanctum.Container", + ), + // 2. ProgID Metadaten & Beschreibung + ( + r"HKCU\Software\Classes\Sanctum.Container", + "", + "Sanctum Verschlüsselter Container", + ), + // 3. Icon + ( + r"HKCU\Software\Classes\Sanctum.Container\DefaultIcon", + "", + &format!("\"{exe_str}\",0"), + ), + // 4. Standard-Doppelklick-Aktion: Mount + ( + r"HKCU\Software\Classes\Sanctum.Container\shell\open", + "", + "In Sanctum öffnen", + ), + ( + r"HKCU\Software\Classes\Sanctum.Container\shell\open\command", + "", + &format!("\"{exe_str}\" mount \"%1\""), + ), + // 5. Kontextmenü-Aktion: Verify / FSCK + ( + r"HKCU\Software\Classes\Sanctum.Container\shell\verify", + "", + "Integrität prüfen (FSCK)", + ), + ( + r"HKCU\Software\Classes\Sanctum.Container\shell\verify\command", + "", + &format!("cmd /k \"\"{exe_str}\" verify \"%1\"\""), + ), + // 6. Kontextmenü-Aktion: Header-Backup + ( + r"HKCU\Software\Classes\Sanctum.Container\shell\backup", + "", + "Header sichern (Disaster Recovery)", + ), + ( + r"HKCU\Software\Classes\Sanctum.Container\shell\backup\command", + "", + &format!("cmd /k \"\"{exe_str}\" backup-header \"%1\"\""), + ), + ]; - for (key, val_name, val_data) in reg_commands { - let mut cmd = Command::new("reg"); - cmd.arg("add").arg(key); - if val_name.is_empty() { - cmd.arg("/ve"); - } else { - cmd.arg("/v").arg(val_name); + for (key, val_name, val_data) in reg_commands { + let mut cmd = Command::new("reg"); + cmd.arg("add").arg(key); + if val_name.is_empty() { + cmd.arg("/ve"); + } else { + cmd.arg("/v").arg(val_name); + } + cmd.arg("/d").arg(val_data).arg("/f"); + + let output = cmd.output().with_context(|| format!("Fehler beim Ausführen von 'reg add {key}'"))?; + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + bail!("Registry-Fehler beim Anlegen von {key}: {stderr}"); + } } - cmd.arg("/d").arg(val_data).arg("/f"); - let output = cmd.output().with_context(|| format!("Fehler beim Ausführen von 'reg add {key}'"))?; - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - bail!("Registry-Fehler beim Anlegen von {key}: {stderr}"); - } + notify_shell_associations_changed(); + Ok(()) } + #[cfg(not(windows))] + { + if let Some(home) = std::env::var_os("HOME") { + let home_path = std::path::PathBuf::from(home); + let apps_dir = home_path.join(".local/share/applications"); + let mime_dir = home_path.join(".local/share/mime/packages"); + let _ = std::fs::create_dir_all(&apps_dir); + let _ = std::fs::create_dir_all(&mime_dir); - notify_shell_associations_changed(); - Ok(()) + let desktop_content = "[Desktop Entry]\nType=Application\nName=Sanctum\nComment=Verschlüsselter Ein-Datei-Container\nExec=sanctum mount %f\nIcon=security-high\nTerminal=true\nMimeType=application/x-sanctum;\nCategories=Utility;Security;\n"; + let _ = std::fs::write(apps_dir.join("sanctum.desktop"), desktop_content); + + let mime_content = "\n\n \n Sanctum Verschlüsselter Container\n \n \n\n"; + let _ = std::fs::write(mime_dir.join("application-x-sanctum.xml"), mime_content); + + notify_shell_associations_changed(); + } + Ok(()) + } } -/// Entfernt die Windows-Explorer-Verknüpfungen aus der Benutzer-Registry (HKCU). +/// Entfernt die Windows-Explorer-Verknüpfungen aus der Benutzer-Registry (HKCU) bzw. unter Linux aus Freedesktop. pub fn unregister_explorer_integration() -> Result<()> { - let keys_to_delete = [ - r"HKCU\Software\Classes\.sanctum", - r"HKCU\Software\Classes\Sanctum.Container", - ]; + #[cfg(windows)] + { + let keys_to_delete = [ + r"HKCU\Software\Classes\.sanctum", + r"HKCU\Software\Classes\Sanctum.Container", + ]; - for key in keys_to_delete { - let _ = Command::new("reg") - .args(["delete", key, "/f"]) - .output(); + for key in keys_to_delete { + let _ = Command::new("reg") + .args(["delete", key, "/f"]) + .output(); + } + + notify_shell_associations_changed(); + Ok(()) + } + #[cfg(not(windows))] + { + if let Some(home) = std::env::var_os("HOME") { + let home_path = std::path::PathBuf::from(home); + let _ = std::fs::remove_file(home_path.join(".local/share/applications/sanctum.desktop")); + let _ = std::fs::remove_file(home_path.join(".local/share/mime/packages/application-x-sanctum.xml")); + notify_shell_associations_changed(); + } + Ok(()) } - - notify_shell_associations_changed(); - Ok(()) } /// Lädt das Windows-Sicherheitsschild-Icon (IDI_SHIELD) oder Anwendungs-Icon für den System-Tray. @@ -259,10 +295,9 @@ pub fn get_default_system_icon() -> Option { /// Guard zur Verwaltung des Hintergrundthreads für die Windows-Sitzungssperre. /// Beim Droppen wird das Win32-Nachrichtenfenster geschlossen und der Thread sauber beendet. +#[cfg(windows)] pub struct SessionLockGuard { - #[cfg(windows)] hwnd: isize, - #[cfg(windows)] join_handle: Option>, }