148 lines
5.3 KiB
C#
148 lines
5.3 KiB
C#
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
|
|
namespace eSuite.WorkBench.Services
|
|
{
|
|
public static class StringExtensions
|
|
{
|
|
public static bool IsHigherVersion(this string currentValue, string potentialHigherValue)
|
|
{
|
|
var currentVersionSplit = currentValue.Split(".");
|
|
var potentialHigherValueSplit = potentialHigherValue.Split(".");
|
|
|
|
//Only checking the first three parts, as the revision is ignored by the MSI installer.
|
|
for( var i = 0; i < 3; i++)
|
|
{
|
|
if (int.Parse(currentVersionSplit[i]) < int.Parse(potentialHigherValueSplit[i]))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public interface IUpdateChecker
|
|
{
|
|
string GetCurrentVersion();
|
|
void CheckForUpdates(string devopsPersonalAccessKey);
|
|
}
|
|
|
|
public class UpdateChecker : IUpdateChecker
|
|
{
|
|
private readonly string _baseUrl = "https://dev.azure.com/sunbranding/f0f62be4-80fd-4c1c-93b6-d019ae74c8cd/_apis";
|
|
|
|
public string GetCurrentVersion()
|
|
{
|
|
var productAssembly = Assembly.GetEntryAssembly();
|
|
var thisAssemblyName = productAssembly.GetName();
|
|
|
|
var assemblyVersion = thisAssemblyName.Version.ToString();
|
|
return assemblyVersion;
|
|
}
|
|
|
|
public void CheckForUpdates(string devopsPersonalAccessKey)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(devopsPersonalAccessKey))
|
|
{
|
|
var authValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"esuite:{devopsPersonalAccessKey}"));
|
|
var message = new HttpRequestMessage
|
|
{
|
|
Method = HttpMethod.Get,
|
|
RequestUri = new Uri($"{_baseUrl}/pipelines/88/runs?api-version=7.0"),
|
|
Headers =
|
|
{
|
|
{HttpRequestHeader.Authorization.ToString(), $"Basic {authValue}" }
|
|
}
|
|
};
|
|
|
|
try
|
|
{
|
|
var client = new HttpClient();
|
|
var response = client.Send(message).EnsureSuccessStatusCode();
|
|
var responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
|
var buildPipelineResults = JsonConvert.DeserializeObject<BuildPipelineResponse>(responseContent);
|
|
|
|
var mostRecentBuild =
|
|
buildPipelineResults.Value.Where(x => x.Result == "succeeded" && x.State == "completed").MaxBy(x=> x.Id);
|
|
|
|
var mostRecentBuildVersion = ExtractVersion(mostRecentBuild.Name);
|
|
var currentRunningVersion = GetCurrentVersion();
|
|
|
|
if (currentRunningVersion.IsHigherVersion(mostRecentBuildVersion))
|
|
{
|
|
DownloadAndUpgrade(authValue, mostRecentBuild.Id);
|
|
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//If the above check fails for any reason, I don't want to raise an exception, just fail silently, the update check will be skipped.
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DownloadAndUpgrade(string authValue, long buildId)
|
|
{
|
|
//Download the Zip file
|
|
var message = new HttpRequestMessage
|
|
{
|
|
Method = HttpMethod.Get,
|
|
RequestUri = new Uri($"{_baseUrl}/build/builds/{buildId}/artifacts?artifactName=installer&api-version=4.1&%24format=zip"),
|
|
Headers =
|
|
{
|
|
{HttpRequestHeader.Authorization.ToString(), $"Basic {authValue}" }
|
|
}
|
|
};
|
|
|
|
var client = new HttpClient();
|
|
var response = client.Send(message).EnsureSuccessStatusCode();
|
|
|
|
//Uncompress the Zip file
|
|
using var readStream = response.Content.ReadAsStream();
|
|
using var archive = new ZipArchive(readStream);
|
|
|
|
const string installerFilename = "eSuite.WorkBench.Installer.msi";
|
|
|
|
var installerArchiveEntry = archive.Entries.Single(x => x.Name == installerFilename);
|
|
using var unzippedMsi = installerArchiveEntry.Open();
|
|
|
|
var filePath = Path.Combine(Path.GetTempPath(), installerFilename);
|
|
|
|
//Delete old installer if found.
|
|
if (File.Exists(filePath))
|
|
File.Delete(filePath);
|
|
|
|
//Save the installer MSI
|
|
using Stream fs = File.Create(filePath);
|
|
unzippedMsi.CopyTo(fs);
|
|
fs.Flush();
|
|
fs.Close();
|
|
|
|
//Launch the msi
|
|
Process process = new Process();
|
|
|
|
// Configure the process using the StartInfo properties.
|
|
process.StartInfo.FileName = filePath;
|
|
process.StartInfo.UseShellExecute = true;
|
|
process.Start();
|
|
|
|
//shutdown
|
|
var currentProcess = Process.GetCurrentProcess();
|
|
currentProcess.Kill();
|
|
}
|
|
|
|
private string ExtractVersion(string name)
|
|
{
|
|
return name.Substring(2, name.IndexOf("-") - 2);
|
|
}
|
|
}
|
|
}
|