Files
carmanager-3/CarManagerV3/Manager/Updater.cs
2026-03-10 16:02:23 +01:00

198 lines
7.8 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 = null;//"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 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)
{
// 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);
}
public static void openReleasePage(string version = null)
{
if(version == null)
{
version = GetLatestVersion(true);
}
string releaseUrl = $"https://git.jaro.digital/{GitRepoOwner}/{GitRepoName}/releases/tag/{version}";
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = releaseUrl,
UseShellExecute = true
});
}
}
}