186 lines
7.6 KiB
C#
186 lines
7.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace CarManagerV3.Manager
|
|
{
|
|
internal class Updater
|
|
{
|
|
|
|
private static readonly string GitApiUrl = "https://git.jaro.digital/api/v1";
|
|
private static readonly string GitRepoOwner = "frozd";
|
|
private static readonly string GitRepoName = "carmanager-3";
|
|
private static readonly string GitApiRepoUrl = $"{GitApiUrl}/repos/{GitRepoOwner}/{GitRepoName}";
|
|
private static readonly string LatestReleaseEndpoint = $"{GitApiRepoUrl}/releases/latest";
|
|
private static readonly string PreReleaseEndpoint = $"{GitApiRepoUrl}/releases?limit=1&pre-release=true";
|
|
private static string latestVersionCache = null;
|
|
private static DateTime lastChecked = DateTime.MinValue;
|
|
private static readonly int CacheDurationMinutes = 60;
|
|
private static bool cacheIncludesPrerelease = false;
|
|
private static readonly string debugVersion = "1.2.0";
|
|
|
|
public static string GetCurrentVersion()
|
|
{
|
|
//DEBUG::
|
|
if(debugVersion != null)
|
|
{
|
|
return debugVersion;
|
|
}
|
|
|
|
var asm = Assembly.GetEntryAssembly()!;
|
|
Version v = asm.GetName().Version ?? new Version(0, 0, 0, 0);
|
|
return v.ToString();
|
|
}
|
|
|
|
private static bool IsCacheValid(bool includePreRelease = false)
|
|
{
|
|
return includePreRelease == cacheIncludesPrerelease && latestVersionCache != null && (DateTime.Now - lastChecked).TotalMinutes < CacheDurationMinutes;
|
|
}
|
|
|
|
private static void InvalidateCache()
|
|
{
|
|
latestVersionCache = null;
|
|
lastChecked = DateTime.MinValue;
|
|
}
|
|
|
|
private static void SetCache(string version, bool includePreRelease = false)
|
|
{
|
|
latestVersionCache = version;
|
|
cacheIncludesPrerelease = includePreRelease;
|
|
lastChecked = DateTime.Now;
|
|
}
|
|
|
|
|
|
public static string GetLatestVersion(bool includePreRelease = false)
|
|
{
|
|
if (IsCacheValid(includePreRelease))
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("Using cached latest version: " + latestVersionCache);
|
|
return latestVersionCache;
|
|
}
|
|
string latestVersion = null;
|
|
// Get the latest stable version first
|
|
using (var client = new System.Net.Http.HttpClient())
|
|
{
|
|
var response = client.GetAsync(LatestReleaseEndpoint).Result;
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var content = response.Content.ReadAsStringAsync().Result;
|
|
dynamic release = Newtonsoft.Json.JsonConvert.DeserializeObject(content);
|
|
latestVersion = release.tag_name;
|
|
}
|
|
}
|
|
// If pre-release is requested, check for the latest pre-release version
|
|
if (includePreRelease)
|
|
{
|
|
using (var client = new System.Net.Http.HttpClient())
|
|
{
|
|
var response = client.GetAsync(PreReleaseEndpoint).Result;
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var content = response.Content.ReadAsStringAsync().Result;
|
|
dynamic releases = Newtonsoft.Json.JsonConvert.DeserializeObject(content);
|
|
if (releases.Count > 0)
|
|
{
|
|
var preReleaseVersion = releases[0].tag_name;
|
|
// Compare versions and return the newer one
|
|
if (IsNewerVersion(preReleaseVersion, latestVersion))
|
|
{
|
|
latestVersion = preReleaseVersion;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
SetCache(latestVersion, includePreRelease);
|
|
return latestVersion;
|
|
|
|
}
|
|
|
|
public static bool IsNewerVersion(string versionA, string versionB)
|
|
{
|
|
if (versionA == null) return false;
|
|
if (versionB == null) return true;
|
|
Version vA = new Version(versionA.TrimStart('v'));
|
|
Version vB = new Version(versionB.TrimStart('v'));
|
|
return vA > vB;
|
|
}
|
|
|
|
|
|
public static async void DownloadNewestInstaller(bool includePreRelease = false)
|
|
{
|
|
string latestVersion = GetLatestVersion(includePreRelease);
|
|
if (latestVersion == null)
|
|
{
|
|
throw new Exception("Could not fetch latest version from Git API.");
|
|
}
|
|
|
|
string releaseUrl = $"{GitApiRepoUrl}/releases/tags/{latestVersion}";
|
|
using (var client = new System.Net.Http.HttpClient())
|
|
{
|
|
var response = client.GetAsync(releaseUrl).Result;
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var content = response.Content.ReadAsStringAsync().Result;
|
|
dynamic release = Newtonsoft.Json.JsonConvert.DeserializeObject(content);
|
|
string downloadUrl = null;
|
|
foreach (var asset in release.assets)
|
|
{
|
|
// file that ends with .msi
|
|
if (asset.name.ToString().EndsWith(".msi"))
|
|
{
|
|
downloadUrl = asset.browser_download_url;
|
|
break;
|
|
}
|
|
}
|
|
if (downloadUrl != null)
|
|
{
|
|
PleaseWait loadForm = new PleaseWait("Downloading the newest version...");
|
|
loadForm.Show();
|
|
Application.DoEvents();
|
|
await Task.Run(() =>
|
|
{
|
|
// Download the installer to the users set Data dir, run it, and then exit the application.
|
|
string tempFilePath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"CarManagerInstaller_{latestVersion}.msi");
|
|
using (var downloadClient = new System.Net.WebClient())
|
|
{
|
|
downloadClient.DownloadFile(downloadUrl, tempFilePath);
|
|
}
|
|
// Use ProcessStartInfo with UseShellExecute to launch the MSI file
|
|
var processStartInfo = new System.Diagnostics.ProcessStartInfo
|
|
{
|
|
FileName = tempFilePath,
|
|
UseShellExecute = true
|
|
};
|
|
System.Diagnostics.Process.Start(processStartInfo);
|
|
});
|
|
|
|
Application.Exit();
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Could not find installer asset in the latest release.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Could not fetch release information from Git API.");
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
public static bool IsUpdateAvailable(bool includePreRelease = false)
|
|
{
|
|
string currentVersion = GetCurrentVersion();
|
|
string latestVersion = GetLatestVersion(includePreRelease);
|
|
return IsNewerVersion(latestVersion, currentVersion);
|
|
}
|
|
}
|
|
}
|