New feature ( #153 ): in-place upgrade
This commit is contained in:
parent
b9e789bbcf
commit
98c3940297
@ -3,7 +3,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Version>7.6.3.1</Version>
|
||||
<Version>7.7.0.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -282,22 +282,20 @@ namespace AppScaffolding
|
||||
});
|
||||
}
|
||||
|
||||
public static (bool hasUpgrade, string zipUrl, string htmlUrl, string zipName) GetLatestRelease()
|
||||
public static UpgradeProperties GetLatestRelease()
|
||||
{
|
||||
(bool, string, string, string) isFalse = (false, null, null, null);
|
||||
|
||||
// timed out
|
||||
var latest = getLatestRelease(TimeSpan.FromSeconds(10));
|
||||
if (latest is null)
|
||||
return isFalse;
|
||||
return null;
|
||||
|
||||
var latestVersionString = latest.TagName.Trim('v');
|
||||
if (!Version.TryParse(latestVersionString, out var latestRelease))
|
||||
return isFalse;
|
||||
return null;
|
||||
|
||||
// we're up to date
|
||||
if (latestRelease <= BuildVersion)
|
||||
return isFalse;
|
||||
return null;
|
||||
|
||||
// we have an update
|
||||
var zip = latest.Assets.FirstOrDefault(a => a.BrowserDownloadUrl.EndsWith(".zip"));
|
||||
@ -310,7 +308,7 @@ namespace AppScaffolding
|
||||
zipUrl
|
||||
});
|
||||
|
||||
return (true, zipUrl, latest.HtmlUrl, zip.Name);
|
||||
return new(zipUrl, latest.HtmlUrl, zip.Name, latestRelease);
|
||||
}
|
||||
private static Octokit.Release getLatestRelease(TimeSpan timeout)
|
||||
{
|
||||
|
||||
6
Source/AppScaffolding/UpgradeProperties.cs
Normal file
6
Source/AppScaffolding/UpgradeProperties.cs
Normal file
@ -0,0 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace AppScaffolding
|
||||
{
|
||||
public record UpgradeProperties(string ZipUrl, string HtmlUrl, string ZipName, Version LatestRelease);
|
||||
}
|
||||
@ -12,7 +12,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dinah.EntityFrameworkCore" Version="4.0.1.1" />
|
||||
<PackageReference Include="Dinah.EntityFrameworkCore" Version="4.1.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
@ -29,7 +29,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<None Update="migrate.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Dinah.Core.Net.Http;
|
||||
|
||||
namespace FileLiberator
|
||||
{
|
||||
// currently only used to download the .zip flies for upgrade
|
||||
public class DownloadFile : Streamable
|
||||
{
|
||||
public async Task<string> PerformDownloadFileAsync(string downloadUrl, string proposedDownloadFilePath)
|
||||
{
|
||||
var client = new HttpClient();
|
||||
|
||||
var progress = new Progress<DownloadProgress>(OnStreamingProgressChanged);
|
||||
|
||||
OnStreamingBegin(proposedDownloadFilePath);
|
||||
|
||||
try
|
||||
{
|
||||
var actualDownloadedFilePath = await client.DownloadFileAsync(downloadUrl, proposedDownloadFilePath, progress);
|
||||
OnFileCreated("Upgrade", actualDownloadedFilePath);
|
||||
return actualDownloadedFilePath;
|
||||
}
|
||||
finally
|
||||
{
|
||||
OnStreamingCompleted(proposedDownloadFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,6 @@ using FileLiberator;
|
||||
|
||||
namespace LibationCli
|
||||
{
|
||||
// streamlined, non-Forms copy of ProcessorAutomationController
|
||||
public abstract class ProcessableOptionsBase : OptionsBase
|
||||
{
|
||||
protected static TProcessable CreateProcessable<TProcessable>(EventHandler<LibraryBook> completedAction = null)
|
||||
|
||||
@ -34,15 +34,15 @@ namespace LibationCli
|
||||
|
||||
private static void checkForUpdate()
|
||||
{
|
||||
var (hasUpgrade, zipUrl, htmlUrl, zipName) = LibationScaffolding.GetLatestRelease();
|
||||
if (!hasUpgrade)
|
||||
var upgradeProperties = LibationScaffolding.GetLatestRelease();
|
||||
if (upgradeProperties is null)
|
||||
return;
|
||||
|
||||
var origColor = Console.ForegroundColor;
|
||||
try
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"UPDATE AVAILABLE @ {zipUrl}");
|
||||
Console.WriteLine($"UPDATE AVAILABLE @ {upgradeProperties.ZipUrl}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@ -421,7 +421,7 @@ namespace LibationFileManager
|
||||
return libationFilesPathCache;
|
||||
|
||||
// FIRST: must write here before SettingsFilePath in next step reads cache
|
||||
libationFilesPathCache = getLiberationFilesSettingFromJson();
|
||||
libationFilesPathCache = getLibationFilesSettingFromJson();
|
||||
|
||||
// SECOND. before setting to json file with SetWithJsonPath, PersistentDictionary must exist
|
||||
persistentDictionary = new PersistentDictionary(SettingsFilePath);
|
||||
@ -443,7 +443,7 @@ namespace LibationFileManager
|
||||
|
||||
private static string libationFilesPathCache;
|
||||
|
||||
private string getLiberationFilesSettingFromJson()
|
||||
private string getLibationFilesSettingFromJson()
|
||||
{
|
||||
string startingContents = null;
|
||||
try
|
||||
@ -482,6 +482,14 @@ namespace LibationFileManager
|
||||
{
|
||||
libationFilesPathCache = null;
|
||||
|
||||
// ensure exists
|
||||
if (!File.Exists(APPSETTINGS_JSON))
|
||||
{
|
||||
// getter creates new file, loads PersistentDictionary
|
||||
var _ = LibationFiles;
|
||||
System.Threading.Thread.Sleep(100);
|
||||
}
|
||||
|
||||
var startingContents = File.ReadAllText(APPSETTINGS_JSON);
|
||||
var jObj = JObject.Parse(startingContents);
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="8.1.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="8.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autoupdater.NET.Official" Version="1.7.0" />
|
||||
<PackageReference Include="Dinah.Core.WindowsDesktop" Version="4.2.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@ -3,14 +3,9 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using AudibleApi.Authorization;
|
||||
using AudibleUtilities;
|
||||
using DataLayer;
|
||||
using Dinah.Core;
|
||||
using LibationFileManager;
|
||||
using LibationWinForms.Dialogs;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Serilog;
|
||||
|
||||
namespace LibationWinForms
|
||||
@ -165,15 +160,12 @@ namespace LibationWinForms
|
||||
|
||||
private static void checkForUpdate()
|
||||
{
|
||||
string zipUrl;
|
||||
string htmlUrl;
|
||||
string zipName;
|
||||
AppScaffolding.UpgradeProperties upgradeProperties;
|
||||
|
||||
try
|
||||
{
|
||||
bool hasUpgrade;
|
||||
(hasUpgrade, zipUrl, htmlUrl, zipName) = AppScaffolding.LibationScaffolding.GetLatestRelease();
|
||||
|
||||
if (!hasUpgrade)
|
||||
upgradeProperties = AppScaffolding.LibationScaffolding.GetLatestRelease();
|
||||
if (upgradeProperties is null)
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -182,36 +174,13 @@ namespace LibationWinForms
|
||||
return;
|
||||
}
|
||||
|
||||
if (zipUrl is null)
|
||||
if (upgradeProperties.ZipUrl is null)
|
||||
{
|
||||
MessageBox.Show(htmlUrl, "New version available");
|
||||
MessageBox.Show(upgradeProperties.HtmlUrl, "New version available");
|
||||
return;
|
||||
}
|
||||
|
||||
var result = MessageBox.Show($"New version available @ {htmlUrl}\r\n\r\nWould you like to upgrade?", "New version available", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
if (result != DialogResult.Yes)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
//Download the upgrader app from github
|
||||
string fileName = "ht" + "tps://github.com/Mbucari/Upgrader/raw/master/Upgrader/win-x86/Upgrader.exe";
|
||||
var cli = new System.Net.Http.HttpClient();
|
||||
var upgrader = cli.GetByteArrayAsync(fileName).GetAwaiter().GetResult();
|
||||
|
||||
|
||||
string upgraderPath = Path.Combine(Path.GetTempPath(), "Upgrader.exe");
|
||||
File.WriteAllBytes(upgraderPath, upgrader);
|
||||
var thisExe = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
|
||||
|
||||
//usage is Upgrader.exe [zip url] [extract directory] [exe to launch]
|
||||
System.Diagnostics.Process.Start(upgraderPath, new string[] { zipUrl, Path.GetDirectoryName(thisExe), "Libation.exe" });
|
||||
Environment.Exit(0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBoxLib.ShowAdminAlert("Error downloading update", "Error downloading update", ex);
|
||||
}
|
||||
Updater.Run(upgradeProperties.LatestRelease, upgradeProperties.ZipUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
50
Source/LibationWinForms/Updater.cs
Normal file
50
Source/LibationWinForms/Updater.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using AutoUpdaterDotNET;
|
||||
|
||||
namespace LibationWinForms
|
||||
{
|
||||
public static class Updater
|
||||
{
|
||||
private const string REPO_URL = "https://github.com/rmcrackan/Libation/releases/latest";
|
||||
|
||||
public static void Run(Version latestVersionOnServer, string downloadZipUrl)
|
||||
=> Run(latestVersionOnServer.ToString(), downloadZipUrl);
|
||||
public static void Run(string latestVersionOnServer, string downloadZipUrl)
|
||||
{
|
||||
AutoUpdater.ParseUpdateInfoEvent +=
|
||||
args => args.UpdateInfo = new()
|
||||
{
|
||||
CurrentVersion = latestVersionOnServer,
|
||||
DownloadURL = downloadZipUrl,
|
||||
ChangelogURL = REPO_URL
|
||||
};
|
||||
AutoUpdater.CheckForUpdateEvent += AutoUpdaterOnCheckForUpdateEvent;
|
||||
AutoUpdater.Start(REPO_URL);
|
||||
}
|
||||
|
||||
private static void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args)
|
||||
{
|
||||
if (args is null || !args.IsUpdateAvailable)
|
||||
return;
|
||||
|
||||
var dialogResult = MessageBox.Show(string.Format(
|
||||
$"There is a new version avilable. Would you like to update?\r\n\r\nAfter you close Libation, the upgrade will start automatically."),
|
||||
"Update Available",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Information);
|
||||
if (dialogResult != DialogResult.Yes)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Serilog.Log.Logger.Information("Start upgrade. {@DebugInfo}", new { CurrentlyInstalled = args.InstalledVersion, TargetVersion = args.CurrentVersion });
|
||||
AutoUpdater.DownloadUpdate(args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBoxLib.ShowAdminAlert("Error downloading update", "Error downloading update", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.6.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="Moq" Version="4.18.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.6.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.6.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.6.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.6.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="Moq" Version="4.18.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user