Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Conceição <Tiago_caza@hotmail.com>2022-10-24 00:19:38 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2022-10-24 00:19:38 +0300
commit18b208bf3170cf42de5f409cd984aedbf34b6e95 (patch)
tree89257d56050c1f2c78e6462bcbaaf91f250e5bb6
parentab11d40d33145e88cf47ebc736349af6eae2dcb9 (diff)
(Improvement) Auto-upgrade procedure for non-Windows systems
-rw-r--r--UVtools.Core/GCode/GCodeBuilder.cs4
-rw-r--r--UVtools.Core/SystemOS/Linux.cs44
-rw-r--r--UVtools.Core/SystemOS/SystemAware.cs18
-rw-r--r--UVtools.Core/SystemOS/macOS.cs43
-rw-r--r--UVtools.WPF/MainWindow.axaml5
-rw-r--r--UVtools.WPF/MainWindow.axaml.cs7
-rw-r--r--UVtools.WPF/Structures/AppVersionChecker.cs143
7 files changed, 180 insertions, 84 deletions
diff --git a/UVtools.Core/GCode/GCodeBuilder.cs b/UVtools.Core/GCode/GCodeBuilder.cs
index d35fb54..a6d98f9 100644
--- a/UVtools.Core/GCode/GCodeBuilder.cs
+++ b/UVtools.Core/GCode/GCodeBuilder.cs
@@ -907,7 +907,7 @@ public class GCodeBuilder : BindableBase
var layerBlock = new GCodeLayer(slicerFile);
- bool parseLayerIndexFromComments = false;
+ //bool parseLayerIndexFromComments = false;
using var reader = new StringReader(gcode);
string? line;
@@ -945,7 +945,7 @@ public class GCodeBuilder : BindableBase
}
layerBlock.SetLayer(true);
layerBlock.LayerIndex = layerIndex;
- parseLayerIndexFromComments = true;
+ //parseLayerIndexFromComments = true;
continue;
}
}
diff --git a/UVtools.Core/SystemOS/Linux.cs b/UVtools.Core/SystemOS/Linux.cs
new file mode 100644
index 0000000..c73fb5a
--- /dev/null
+++ b/UVtools.Core/SystemOS/Linux.cs
@@ -0,0 +1,44 @@
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+
+using System;
+using System.IO;
+
+namespace UVtools.Core.SystemOS;
+
+/// <summary>
+/// Linux specific methods
+/// </summary>
+public static class Linux
+{
+ /// <summary>
+ /// Gets if is running under Linux and under AppImage format
+ /// </summary>
+ public static bool IsRunningAppImage => !string.IsNullOrWhiteSpace(RunningAppImageRootPath);
+
+ /// <summary>
+ /// Gets if is running under Linux and under AppImage format and return the full root path for the running AppImage
+ /// </summary>
+ public static bool IsRunningAppImageGetPath(out string? path)
+ {
+ path = RunningAppImageRootPath;
+ return !string.IsNullOrWhiteSpace(path);
+ }
+
+ /// <summary>
+ /// <para>Gets the full root path for the running AppImage. Returns null is not Linux and null/empty if not an AppImage</para>
+ /// <para>The return path is the source file location and not the execution path location.</para>
+ /// </summary>
+ public static string? RunningAppImageRootPath => OperatingSystem.IsLinux() ? Environment.GetEnvironmentVariable("APPIMAGE") : null;
+
+
+ /// <summary>
+ /// Gets the name of the running *.app. Returns null or empty if not running an macOS .app. Returns null or empty if not an AppImage
+ /// </summary>
+ public static string? RunningAppName => Path.GetFileName(RunningAppImageRootPath);
+} \ No newline at end of file
diff --git a/UVtools.Core/SystemOS/SystemAware.cs b/UVtools.Core/SystemOS/SystemAware.cs
index a3781cb..c73c0aa 100644
--- a/UVtools.Core/SystemOS/SystemAware.cs
+++ b/UVtools.Core/SystemOS/SystemAware.cs
@@ -363,24 +363,14 @@ public static class SystemAware
/// <summary>
/// Gets if is running under Linux and under AppImage format
/// </summary>
- public static bool IsRunningLinuxAppImage(out string? path)
- {
- path = null;
- if (!OperatingSystem.IsLinux()) return false;
- path = Environment.GetEnvironmentVariable("APPIMAGE");
- return !string.IsNullOrWhiteSpace(path);
- }
-
- /// <summary>
- /// Gets if is running under Linux and under AppImage format
- /// </summary>
/// <returns></returns>
- public static bool IsRunningLinuxAppImage() => IsRunningLinuxAppImage(out _);
+ public static bool IsRunningLinuxAppImage => Linux.IsRunningAppImage;
/// <summary>
- /// Gets if is running under MacOS and under app format
+ /// Gets if is running under MacOS and under *.app format
/// </summary>
- public static bool IsRunningMacOSApp => OperatingSystem.IsMacOS() && AppContext.BaseDirectory.EndsWith(Path.Combine(".app", "Contents", $"MacOS{Path.DirectorySeparatorChar}"));
+ public static bool IsRunningMacOSApp => macOS.IsRunningApp;
+
/// <summary>
/// Gets the main name of the operative system
diff --git a/UVtools.Core/SystemOS/macOS.cs b/UVtools.Core/SystemOS/macOS.cs
new file mode 100644
index 0000000..fca55b3
--- /dev/null
+++ b/UVtools.Core/SystemOS/macOS.cs
@@ -0,0 +1,43 @@
+/*
+ * GNU AFFERO GENERAL PUBLIC LICENSE
+ * Version 3, 19 November 2007
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ */
+
+using System;
+using System.IO;
+
+namespace UVtools.Core.SystemOS;
+
+/// <summary>
+/// MacOS specific methods
+/// </summary>
+public static class macOS
+{
+ /// <summary>
+ /// Gets if is running under MacOS and under .app format
+ /// </summary>
+ public static bool IsRunningApp => OperatingSystem.IsMacOS() && AppContext.BaseDirectory.EndsWith(Path.Combine(".app", "Contents", $"MacOS{Path.DirectorySeparatorChar}"));
+
+ /// <summary>
+ /// Gets if is running under macOS and under .app format and return the full root path for the running .app
+ /// </summary>
+ public static bool IsRunningAppGetPath(out string? path)
+ {
+ path = RunningAppRootPath;
+ return !string.IsNullOrWhiteSpace(path);
+ }
+
+ /// <summary>
+ /// Gets the full root path for the running .app. Returns null or empty if not running an macOS .app
+ /// </summary>
+ public static string? RunningAppRootPath => IsRunningApp ? Directory.GetParent(AppContext.BaseDirectory)?.Parent?.Parent?.FullName : null;
+
+
+ /// <summary>
+ /// Gets the name of the running .app. Returns null or empty if not running an macOS .app
+ /// </summary>
+ public static string? RunningAppName => IsRunningApp ? Directory.GetParent(AppContext.BaseDirectory)?.Parent?.Parent?.Name : null;
+} \ No newline at end of file
diff --git a/UVtools.WPF/MainWindow.axaml b/UVtools.WPF/MainWindow.axaml
index 5adbec4..2809327 100644
--- a/UVtools.WPF/MainWindow.axaml
+++ b/UVtools.WPF/MainWindow.axaml
@@ -245,6 +245,11 @@
IsVisible="{Binding IsDebug}"
Command="{Binding MenuHelpDebugLongMessageBoxClicked}"
i:MenuItem.Icon="fa-solid fa-message"/>
+
+ <MenuItem Header="Trigger new update"
+ IsVisible="{Binding IsDebug}"
+ Command="{Binding MenuHelpDebugTriggerNewUpdateClicked}"
+ i:MenuItem.Icon="fa-solid fa-cloud-arrow-up"/>
</MenuItem>
diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs
index fc393df..08f20c2 100644
--- a/UVtools.WPF/MainWindow.axaml.cs
+++ b/UVtools.WPF/MainWindow.axaml.cs
@@ -755,7 +755,7 @@ public partial class MainWindow : WindowEx
if (Settings.General.CheckForUpdatesOnStartup)
{
- Task.Factory.StartNew(VersionChecker.Check);
+ Task.Factory.StartNew(() => VersionChecker.Check());
}
ProcessFiles(Program.Args);
@@ -1186,6 +1186,11 @@ public partial class MainWindow : WindowEx
await this.MessageBoxError(string.Concat(Enumerable.Repeat("Informative message:\n\nLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.\n", 100)));
}
+ public void MenuHelpDebugTriggerNewUpdateClicked()
+ {
+ VersionChecker.Check(true);
+ }
+
public async void MenuNewVersionClicked()
{
if (string.IsNullOrWhiteSpace(VersionChecker.DownloadLink))
diff --git a/UVtools.WPF/Structures/AppVersionChecker.cs b/UVtools.WPF/Structures/AppVersionChecker.cs
index 650c137..f7cd6df 100644
--- a/UVtools.WPF/Structures/AppVersionChecker.cs
+++ b/UVtools.WPF/Structures/AppVersionChecker.cs
@@ -13,11 +13,8 @@ using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using System.Text.Json.Nodes;
-using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
-using System.Xml.Linq;
-using Avalonia.Threading;
using UVtools.Core;
using UVtools.Core.Extensions;
using UVtools.Core.Objects;
@@ -47,7 +44,7 @@ public class AppVersionChecker : BindableBase
if (!string.IsNullOrWhiteSpace(package) && (package.EndsWith("-x64") || package.EndsWith("-arm64")))
{
if (OperatingSystem.IsWindows()) return $"{About.Software}_{package}_v{_version}.msi";
- if (SystemAware.IsRunningLinuxAppImage()) return $"{About.Software}_{package}_v{_version}.AppImage";
+ if (Linux.IsRunningAppImage) return $"{About.Software}_{package}_v{_version}.AppImage";
return $"{About.Software}_{package}_v{_version}.zip";
}
}
@@ -63,7 +60,7 @@ public class AppVersionChecker : BindableBase
}
if (OperatingSystem.IsLinux())
{
- return SystemAware.IsRunningLinuxAppImage()
+ return Linux.IsRunningAppImage
? $"{About.Software}_linux-x64_v{_version}.AppImage"
: $"{About.Software}_linux-x64_v{_version}.zip";
}
@@ -126,7 +123,12 @@ public class AppVersionChecker : BindableBase
public string DownloadedFile { get; private set; }
- public bool Check()
+ /// <summary>
+ /// Check for new version
+ /// </summary>
+ /// <param name="alwaysTrigger">True to always found as new update, otherwise it will compare versions and trigger only if a new version is found</param>
+ /// <returns></returns>
+ public bool Check(bool alwaysTrigger = false)
{
try
{
@@ -149,7 +151,7 @@ public class AppVersionChecker : BindableBase
Debug.WriteLine($"Version checker: v{About.VersionStr} <=> v{tag_name}");
Version checkVersion = new(tag_name);
Changelog = json["body"]?.ToString();
- if (About.Version.CompareTo(checkVersion) < 0)
+ if (alwaysTrigger || About.Version.CompareTo(checkVersion) < 0)
{
var assets = json["assets"].AsArray();
@@ -201,78 +203,85 @@ public class AppVersionChecker : BindableBase
if (OperatingSystem.IsWindows())
{
SystemAware.StartProcess(DownloadedFile);
- Environment.Exit(0);
}
- else
+ else if (downloadFilename.EndsWith(".AppImage") && Linux.IsRunningAppImageGetPath(out var appImagePath)) // Linux AppImage
{
- // Linux AppImage
- if (downloadFilename.EndsWith(".AppImage") && SystemAware.IsRunningLinuxAppImage(out var appImagePath))
- {
- var directory = Path.GetDirectoryName(appImagePath);
- //var oldFileName = Path.GetFileName(appImagePath);
- // Try to keep same filename logic if user renamed the file, like UVtools.AppImage would keep same same
- //var newFilename = Regex.Replace(oldFileName, @"v\d+.\d+.\d+", $"v{_version}");
- var newFullPath = Path.Combine(directory, downloadFilename);
-
- if (File.Exists(appImagePath)) File.Delete(appImagePath);
- File.Move(DownloadedFile, newFullPath, true);
- SystemAware.StartProcess("chmod", $"a+x \"{newFullPath}\"", true);
- Thread.Sleep(500);
- SystemAware.StartProcess(newFullPath);
- }
- else // MacOS and generic linux (no AppImage)
+ var directory = Path.GetDirectoryName(appImagePath);
+ //var oldFileName = Path.GetFileName(appImagePath);
+ // Try to keep same filename logic if user renamed the file, like UVtools.AppImage would keep same same
+ //var newFilename = Regex.Replace(oldFileName, @"v\d+.\d+.\d+", $"v{_version}");
+ var newFullPath = Path.Combine(directory, downloadFilename);
+
+ if (File.Exists(appImagePath)) File.Delete(appImagePath);
+ File.Move(DownloadedFile, newFullPath, true);
+ SystemAware.StartProcess("chmod", $"a+x \"{newFullPath}\"", true);
+ Thread.Sleep(500);
+ SystemAware.StartProcess(newFullPath);
+ }
+ else // MacOS and generic linux (no AppImage -- plain zip)
+ {
+ var tmpDirectory = PathExtensions.GetTemporaryDirectory("UVtoolsUpdate-", true);
+ var extractDirectoryPath = Path.Combine(tmpDirectory, "extracted");
+
+ ZipFile.ExtractToDirectory(DownloadedFile, extractDirectoryPath, true);
+ File.Delete(DownloadedFile);
+
+ var upgradeScriptFileName = "upgrade.sh";
+ var upgradeScriptFilePath = Path.Combine(tmpDirectory, upgradeScriptFileName);
+ await using (var stream = File.CreateText(upgradeScriptFilePath))
{
- var upgradeFolder = "UPDATED_VERSION";
- var targetDir = Path.Combine(App.ApplicationPath, upgradeFolder);
- await using (var stream = File.Open(DownloadedFile, FileMode.Open))
+ stream.NewLine = "\n";
+ await stream.WriteLineAsync("#!/bin/bash");
+ await stream.WriteLineAsync();
+ await stream.WriteLineAsync("testcmd() { command -v \"$1\" &> /dev/null; }");
+ await stream.WriteLineAsync();
+ await stream.WriteLineAsync("cd \"$(dirname \"$0\")\"");
+ await stream.WriteLineAsync($"echo '{About.Software} v{About.VersionStr} updater script'");
+ await stream.WriteLineAsync();
+ //await stream.WriteLineAsync($"cd '{App.ApplicationPath}'");
+ await stream.WriteLineAsync($"killall {About.Software}");
+ await stream.WriteLineAsync("sleep 1");
+ await stream.WriteLineAsync();
+
+ if (OperatingSystem.IsMacOS())
{
- using ZipArchive zip = new(stream, ZipArchiveMode.Read);
- zip.ExtractToDirectory(targetDir, true);
+ await stream.WriteLineAsync($"find '{extractDirectoryPath}' -print0 | xargs -0 xattr -d com.apple.quarantine &> /dev/null");
}
- File.Delete(DownloadedFile);
-
- var upgradeFileName = $"{About.Software}_upgrade.sh";
- var upgradeFile = Path.Combine(App.ApplicationPath, upgradeFileName);
- await using (var stream = File.CreateText(upgradeFile))
+ if (macOS.IsRunningAppGetPath(out var macOSAppPath) && Directory.Exists(Path.Combine(extractDirectoryPath, "UVtools.app")))
{
- stream.NewLine = "\n";
- await stream.WriteLineAsync("#!/bin/bash");
- await stream.WriteLineAsync($"echo {About.Software} v{About.Version} updater script");
- await stream.WriteLineAsync($"cd '{App.ApplicationPath}'");
- await stream.WriteLineAsync($"killall {About.Software}");
- await stream.WriteLineAsync("sleep 1");
-
-
- //stream.WriteLine($"[ -f {About.Software} ] && {App.AppExecutableQuoted} & || dotnet {About.Software}.dll &");
- if (SystemAware.IsRunningMacOSApp)
- {
- await stream.WriteLineAsync($"find '{upgradeFolder}' -print0 | xargs -0 xattr -d com.apple.quarantine");
- await stream.WriteLineAsync($"cp -fR {upgradeFolder}/* ../../../");
- await stream.WriteLineAsync($"open ../../../{About.Software}.app");
- }
- else // Linux generic
- {
- await stream.WriteLineAsync($"cp -fR {upgradeFolder}/* .");
- await stream.WriteLineAsync($"if [ -f '{About.Software}' ]; then");
- await stream.WriteLineAsync($" ./{About.Software} &");
- await stream.WriteLineAsync("else");
- await stream.WriteLineAsync($" dotnet {About.Software}.dll &");
- await stream.WriteLineAsync("fi");
- }
-
- await stream.WriteLineAsync($"rm -fr {upgradeFolder}");
- await stream.WriteLineAsync("sleep 0.5");
- await stream.WriteLineAsync($"rm -f {upgradeFileName}");
- //stream.WriteLine("exit");
+ await stream.WriteLineAsync("if testcmd rsync; then");
+ await stream.WriteLineAsync($" rsync -arctxv --delete --remove-source-files --stats '{Path.Combine(extractDirectoryPath, "UVtools.app")}/' '{macOSAppPath}'");
+ await stream.WriteLineAsync("else");
+ await stream.WriteLineAsync($" cp -fR '{extractDirectoryPath}/'* '{macOSAppPath}'");
+ await stream.WriteLineAsync("fi");
+ //await stream.WriteLineAsync($"open '{macOSAppPath}'");
+ }
+ else // Linux generic and macOS generic
+ {
+ await stream.WriteLineAsync("if testcmd rsync; then");
+ await stream.WriteLineAsync($" rsync -arctxv --remove-source-files --stats '{extractDirectoryPath}/' '{App.ApplicationPath}'");
+ await stream.WriteLineAsync("else");
+ await stream.WriteLineAsync($" cp -fR '{extractDirectoryPath}/'* '{App.ApplicationPath}'");
+ await stream.WriteLineAsync("fi");
}
- SystemAware.StartProcess("bash", $"\"{upgradeFile}\"");
- //App.NewInstance(App.MainWindow.SlicerFile?.FileFullPath);
+ await stream.WriteLineAsync();
+ await stream.WriteLineAsync($"nohup bash '{Path.Combine(App.ApplicationPath, "UVtools.sh")}' &> /dev/null &");
+ await stream.WriteLineAsync("disown");
+ await stream.WriteLineAsync();
+ await stream.WriteLineAsync($"rm -fr '{tmpDirectory}'");
+ //await stream.WriteLineAsync("sleep 0.5");
+ //await stream.WriteLineAsync($"rm -f {upgradeScriptFileName}");
+ //await stream.WriteLine("exit");
}
- Environment.Exit(0);
+ SystemAware.StartProcess("bash", $"\"{upgradeScriptFilePath}\"");
+ //App.NewInstance(App.MainWindow.SlicerFile?.FileFullPath);
}
+
+ Environment.Exit(0);
+ return true;
}
catch (OperationCanceledException)
{