diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs index 40131ee01..5635e75e3 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs @@ -162,6 +162,68 @@ await updateHelper.DownloadUpdate( ); } + // Handle Linux AppImage update + if (Compat.IsLinux && Environment.GetEnvironmentVariable("APPIMAGE") is { } appImage) + { + try + { + var updateScriptPath = UpdateHelper.UpdateFolder.JoinFile("update_script.sh").FullPath; + var newAppImage = UpdateHelper.ExecutablePath.FullPath; + + var scriptContent = """ +#!/bin/bash +set -e + +# Wait for the process to exit +while kill -0 "$PID" 2>/dev/null; do + sleep 0.5 +done + +# Move the new AppImage over the old one +mv -f "$NEW_APPIMAGE" "$OLD_APPIMAGE" +chmod +x "$OLD_APPIMAGE" + +# Launch the new AppImage detached +"$OLD_APPIMAGE" > /dev/null 2>&1 & +disown +"""; + await File.WriteAllTextAsync(updateScriptPath, scriptContent); + + File.SetUnixFileMode( + updateScriptPath, + UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute + ); + + var startInfo = new System.Diagnostics.ProcessStartInfo + { + FileName = "/usr/bin/env", + Arguments = $"bash \"{updateScriptPath}\"", + UseShellExecute = false, + CreateNoWindow = true, + }; + + startInfo.EnvironmentVariables["PID"] = Environment.ProcessId.ToString(); + startInfo.EnvironmentVariables["NEW_APPIMAGE"] = newAppImage; + startInfo.EnvironmentVariables["OLD_APPIMAGE"] = appImage; + + System.Diagnostics.Process.Start(startInfo); + + App.Shutdown(); + return; + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to execute AppImage update script"); + + var dialog = DialogHelper.CreateMarkdownDialog( + "AppImage update script failed. \nCould not replace old AppImage with new version. Please check directory permissions. \nFalling back to standard update process. User intervention required: \nAfter program closes, \nplease move the new AppImage extracted in the '.StabilityMatrixUpdate' hidden directory to the old AppImage overwriting it. \n\nClose this dialog to continue with standard update process.", + Resources.Label_UnexpectedErrorOccurred + ); + + await dialog.ShowAsync(); + } + } + // Set current version for update messages settingsManager.Transaction( s => s.UpdatingFromVersion = Compat.AppVersion,