Explorar el Código

Exe downloader works

flabbet hace 4 años
padre
commit
0239974121

+ 2 - 0
PixiEditor.UpdateModule/ReleaseInfo.cs

@@ -24,6 +24,8 @@ namespace PixiEditor.UpdateModule
 
         [JsonPropertyName("assets")]
         public Asset[] Assets { get; set; }
+        [JsonPropertyName("target_commitish")]
+        public string TargetCommitish { get; set; }
 
         public bool WasDataFetchSuccessful { get; set; } = true;
     }

+ 31 - 6
PixiEditor.UpdateModule/UpdateChecker.cs

@@ -1,4 +1,6 @@
-using System.Globalization;
+using System;
+using System.Globalization;
+using System.Linq;
 using System.Net;
 using System.Net.Http;
 using System.Text.Json;
@@ -9,6 +11,7 @@ namespace PixiEditor.UpdateModule
     public class UpdateChecker
     {
         private const string ReleaseApiUrl = "https://api.github.com/repos/PixiEditor/PixiEditor/releases/latest";
+        private const string IncompatibleFileApiUrl = "https://api.github.com/repos/PixiEditor/PixiEditor/contents/incompatible.json";
 
         public UpdateChecker(string currentVersionTag)
         {
@@ -22,9 +25,9 @@ namespace PixiEditor.UpdateModule
         /// <summary>
         ///     Compares version strings and returns true if newVer > originalVer.
         /// </summary>
-        /// <param name="originalVer" />
-        /// <param name="newVer"></param>
-        /// <returns></returns>
+        /// <param name="originalVer">Version to compare</param>
+        /// <param name="newVer">Version to compare with</param>
+        /// <returns>True if semantic version is higher</returns>
         public static bool VersionBigger(string originalVer, string newVer)
         {
             if (!ParseVersionString(originalVer, out float ver1))
@@ -42,7 +45,7 @@ namespace PixiEditor.UpdateModule
 
         public async Task<bool> CheckUpdateAvailable()
         {
-            LatestReleaseInfo = await GetLatestReleaseInfo_Async();
+            LatestReleaseInfo = await GetLatestReleaseInfoAsync();
             return CheckUpdateAvailable(LatestReleaseInfo);
         }
 
@@ -51,7 +54,29 @@ namespace PixiEditor.UpdateModule
             return latestRelease.WasDataFetchSuccessful && VersionBigger(CurrentVersionTag, latestRelease.TagName);
         }
 
-        private static async Task<ReleaseInfo> GetLatestReleaseInfo_Async()
+        public async Task<bool> IsUpdateCompatible()
+        {
+            string[] incompatibleVersions = await GetUpdateIncompatibleVersionsAsync(LatestReleaseInfo.TargetCommitish);
+            return !incompatibleVersions.Contains(CurrentVersionTag);
+        }
+
+        private async Task<string[]> GetUpdateIncompatibleVersionsAsync(string targetCommitish)
+        {
+            using (HttpClient client = new HttpClient())
+            {
+                client.DefaultRequestHeaders.Add("User-Agent", "PixiEditor");
+                HttpResponseMessage response = await client.GetAsync(IncompatibleFileApiUrl + $"?ref={targetCommitish}");
+                if (response.StatusCode == HttpStatusCode.OK)
+                {
+                    string content = await response.Content.ReadAsStringAsync();
+                    return JsonSerializer.Deserialize<string[]>(content);
+                }
+            }
+
+            return Array.Empty<string>();
+        }
+
+        private static async Task<ReleaseInfo> GetLatestReleaseInfoAsync()
         {
             using (HttpClient client = new HttpClient())
             {

+ 20 - 2
PixiEditor.UpdateModule/UpdateDownloader.cs

@@ -29,6 +29,24 @@ namespace PixiEditor.UpdateModule
             }
         }
 
+        public static async Task DownloadInstaller(ReleaseInfo info)
+        {
+            Asset matchingAsset = GetMatchingAsset(info, "application/x-msdownload");
+
+            using (HttpClient client = new HttpClient())
+            {
+                client.DefaultRequestHeaders.Add("User-Agent", "PixiEditor");
+                client.DefaultRequestHeaders.Add("Accept", "application/octet-stream");
+                var response = await client.GetAsync(matchingAsset.Url);
+                if (response.StatusCode == HttpStatusCode.OK)
+                {
+                    byte[] bytes = await response.Content.ReadAsByteArrayAsync();
+                    CreateTempDirectory();
+                    File.WriteAllBytes(Path.Join(DownloadLocation, $"update-{info.TagName}.exe"), bytes);
+                }
+            }
+        }
+
         public static void CreateTempDirectory()
         {
             if (!Directory.Exists(DownloadLocation))
@@ -37,10 +55,10 @@ namespace PixiEditor.UpdateModule
             }
         }
 
-        private static Asset GetMatchingAsset(ReleaseInfo release)
+        private static Asset GetMatchingAsset(ReleaseInfo release, string assetType = "zip")
         {
             string arch = IntPtr.Size == 8 ? "x64" : "x86";
-            return release.Assets.First(x => x.ContentType.Contains("zip")
+            return release.Assets.First(x => x.ContentType.Contains(assetType)
             && x.Name.Contains(arch));
         }
     }

+ 18 - 0
PixiEditor/Helpers/AssemblyHelper.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Text;
+
+namespace PixiEditor.Helpers
+{
+    public static class AssemblyHelper
+    {
+        public static string GetCurrentAssemblyVersion()
+        {
+            var assembly = Assembly.GetExecutingAssembly();
+            FileVersionInfo info = FileVersionInfo.GetVersionInfo(assembly.Location);
+            return info.FileVersion;
+        }
+    }
+}

+ 13 - 5
PixiEditor/ViewModels/SubViewModels/Main/UpdateViewModel.cs

@@ -54,12 +54,21 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
             return await Task.Run(async () =>
             {
                 bool updateAvailable = await UpdateChecker.CheckUpdateAvailable();
+                bool updateCompatible = await UpdateChecker.IsUpdateCompatible();
                 bool updateFileDoesNotExists = !File.Exists(
                     Path.Join(UpdateDownloader.DownloadLocation, $"update-{UpdateChecker.LatestReleaseInfo.TagName}.zip"));
                 if (updateAvailable && updateFileDoesNotExists)
                 {
                     VersionText = "Downloading update...";
-                    await UpdateDownloader.DownloadReleaseZip(UpdateChecker.LatestReleaseInfo);
+                    if (!updateCompatible)
+                    {
+                        await UpdateDownloader.DownloadReleaseZip(UpdateChecker.LatestReleaseInfo);
+                    }
+                    else
+                    {
+                        await UpdateDownloader.DownloadInstaller(UpdateChecker.LatestReleaseInfo);
+                    }
+
                     VersionText = "to install update"; // Button shows "Restart" before this text
                     UpdateReadyToInstall = true;
                     return true;
@@ -93,10 +102,9 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
         private void InitUpdateChecker()
         {
-            var assembly = Assembly.GetExecutingAssembly();
-            FileVersionInfo info = FileVersionInfo.GetVersionInfo(assembly.Location);
-            UpdateChecker = new UpdateChecker(info.FileVersion);
-            VersionText = $"Version {info.FileVersion}";
+            string version = AssemblyHelper.GetCurrentAssemblyVersion();
+            UpdateChecker = new UpdateChecker(version);
+            VersionText = $"Version {version}";
         }
     }
 }

+ 1 - 1
PixiEditor/Views/MainWindow.xaml

@@ -13,7 +13,7 @@
         xmlns:cmd="http://www.galasoft.ch/mvvmlight" 
         xmlns:avalondock="https://github.com/Dirkster99/AvalonDock"
         xmlns:colorpicker="clr-namespace:ColorPicker;assembly=ColorPicker"
-        mc:Ignorable="d" WindowStyle="None" Initialized="mainWindow_Initialized"
+        mc:Ignorable="d" WindowStyle="None" Initialized="MainWindow_Initialized"
         Title="PixiEditor" Name="mainWindow" Height="1000" Width="1600" Background="{StaticResource MainColor}"
         WindowStartupLocation="CenterScreen" WindowState="Maximized" DataContext="{DynamicResource ViewModelMain}">
     <WindowChrome.WindowChrome>

+ 27 - 6
PixiEditor/Views/MainWindow.xaml.cs

@@ -5,6 +5,7 @@ using System.IO;
 using System.Reflection;
 using System.Windows;
 using System.Windows.Input;
+using PixiEditor.Helpers;
 using PixiEditor.Models.Processes;
 using PixiEditor.UpdateModule;
 using PixiEditor.ViewModels;
@@ -69,23 +70,43 @@ namespace PixiEditor
             }
         }
 
-        private void mainWindow_Initialized(object sender, EventArgs e)
+        private void MainWindow_Initialized(object sender, EventArgs e)
         {
             string dir = AppDomain.CurrentDomain.BaseDirectory;
             UpdateDownloader.CreateTempDirectory();
-            bool updateFileExists = Directory.GetFiles(UpdateDownloader.DownloadLocation, "update-*.zip").Length > 0;
+            bool updateZipExists = Directory.GetFiles(UpdateDownloader.DownloadLocation, "update-*.zip").Length > 0;
+            string[] updateExeFiles = Directory.GetFiles(UpdateDownloader.DownloadLocation, "update-*.exe");
+            bool updateExeExists = updateExeFiles.Length > 0;
+
             string updaterPath = Path.Join(dir, "PixiEditor.UpdateInstaller.exe");
-            if (updateFileExists && File.Exists(updaterPath))
+            if (updateZipExists && File.Exists(updaterPath))
             {
                 try
                 {
                     ProcessHelper.RunAsAdmin(updaterPath);
                     Close();
                 }
-                catch(Win32Exception)
+                catch (Win32Exception)
+                {
+                    MessageBox.Show(
+                        "Couldn't update without administrator rights.",
+                        "Insufficient permissions",
+                        MessageBoxButton.OK,
+                        MessageBoxImage.Error);
+                }
+            }
+            else if (updateExeExists)
+            {
+                bool alreadyUpdated = AssemblyHelper.GetCurrentAssemblyVersion() ==
+                    updateExeFiles[0].Split('-')[1].Split(".exe")[0];
+                if (!alreadyUpdated)
+                {
+                    Process.Start(updateExeFiles[0]);
+                    Close();
+                }
+                else
                 {
-                    MessageBox.Show("Couldn't update without administrator rights.", "Insufficient permissions", 
-                        MessageBoxButton.OK, MessageBoxImage.Error);
+                    File.Delete(updateExeFiles[0]);
                 }
             }
         }