From 7f6a7be3dce3c83e36d01392576e34c96fd8bbbb Mon Sep 17 00:00:00 2001 From: "waffle.lord" Date: Sat, 18 Mar 2023 10:44:52 -0400 Subject: [PATCH] add dependency checks, add install path prompt --- Aki.Core/Model/GenericResult.cs | 5 +- Aki.Core/Model/LiveTableTaskRunner.cs | 11 ++- Aki.Core/SPTInstaller.cs | 8 ++ Aki.Core/Tasks/DependencyCheckTask.cs | 106 ++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 Aki.Core/Tasks/DependencyCheckTask.cs diff --git a/Aki.Core/Model/GenericResult.cs b/Aki.Core/Model/GenericResult.cs index 6700813..c59d7b7 100644 --- a/Aki.Core/Model/GenericResult.cs +++ b/Aki.Core/Model/GenericResult.cs @@ -5,14 +5,17 @@ public string Message { get; private set; } public bool Succeeded { get; private set; } + public bool NonCritical { get; private set; } - protected GenericResult(string message, bool succeeded) + protected GenericResult(string message, bool succeeded, bool nonCritical = false) { Message = message; Succeeded = succeeded; + NonCritical = nonCritical; } public static GenericResult FromSuccess(string message = "") => new GenericResult(message, true); public static GenericResult FromError(string errorMessage) => new GenericResult(errorMessage, false); + public static GenericResult FromWarning(string warningMessage) => new GenericResult(warningMessage, false, true); } } diff --git a/Aki.Core/Model/LiveTableTaskRunner.cs b/Aki.Core/Model/LiveTableTaskRunner.cs index be8ee98..6d4a5b2 100644 --- a/Aki.Core/Model/LiveTableTaskRunner.cs +++ b/Aki.Core/Model/LiveTableTaskRunner.cs @@ -23,12 +23,21 @@ namespace SPT_AKI_Installer.Aki.Core.Model var result = await task.RunAsync(); - if (!result.Succeeded) + // critical: error - stop installer + if (!result.Succeeded && !result.NonCritical) { task.SetStatus($"[red]{result.Message.EscapeMarkup()}[/]"); return (false, task); } + // non-critical: warning - continue + if (!result.Succeeded && result.NonCritical) + { + task.SetStatus($"[yellow]{result.Message.EscapeMarkup()}[/]"); + continue; + } + + //suceeded: continue task.SetStatus($"[green]{(result.Message == "" ? "Complete" : $"{result.Message.EscapeMarkup()}")}[/]"); } diff --git a/Aki.Core/SPTInstaller.cs b/Aki.Core/SPTInstaller.cs index 1b7014f..0a2cfa8 100644 --- a/Aki.Core/SPTInstaller.cs +++ b/Aki.Core/SPTInstaller.cs @@ -43,6 +43,8 @@ namespace SPT_AKI_Installer.Aki.Core { _data.TargetInstallPath = Environment.CurrentDirectory; + var cursorPos = Console.GetCursorPosition(); + #if DEBUG var path = AnsiConsole.Ask("[purple]DEBUG[/] [blue]::[/] Enter path to install folder: ").Replace("\"", ""); @@ -53,7 +55,12 @@ namespace SPT_AKI_Installer.Aki.Core _data.TargetInstallPath = path; #endif + var continueInstall = AnsiConsole.Confirm($"SPT will install into:\n[blue]{_data.TargetInstallPath}[/]\n\nContinue?", false); + if (!continueInstall) CloseApp("Please move the installer to the folder you want to install into"); + + + Console.SetCursorPosition(cursorPos.Left, cursorPos.Top); await LiveTableTaskRunner.RunAsync(tasks); CloseApp(""); } @@ -63,6 +70,7 @@ namespace SPT_AKI_Installer.Aki.Core return Host.CreateDefaultBuilder().ConfigureServices((_, services) => { services.AddSingleton(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/Aki.Core/Tasks/DependencyCheckTask.cs b/Aki.Core/Tasks/DependencyCheckTask.cs new file mode 100644 index 0000000..06df724 --- /dev/null +++ b/Aki.Core/Tasks/DependencyCheckTask.cs @@ -0,0 +1,106 @@ +using Microsoft.Win32; +using SPT_AKI_Installer.Aki.Core.Model; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SPT_AKI_Installer.Aki.Core.Tasks +{ + public class DependencyCheckTask : LiveTableTask + { + private bool CheckNetCore6Installed() + { + var minRequiredVersion = new Version("6.0.0"); + string[] output; + + try + { + var proc = Process.Start(new ProcessStartInfo() + { + FileName = "dotnet", + Arguments = "--list-runtimes", + RedirectStandardOutput = true + }); + + proc.WaitForExit(); + + output = proc.StandardOutput.ReadToEnd().Split("\r\n"); + } + catch + { + return false; + } + + foreach(var lineVersion in output) + { + if (lineVersion.StartsWith("Microsoft.WindowsDesktop.App") && lineVersion.Split(" ").Length > 1) + { + string stringVerion = lineVersion.Split(" ")[1]; + + var foundVersion = new Version(stringVerion); + + // not fully sure if we should only check for 6.x.x versions or if higher major versions are ok -waffle + if(foundVersion >= minRequiredVersion) + { + return true; + } + } + } + + return false; + } + + private bool CheckNet472Installed() + { + var minRequiredVersion = new Version("4.7.2"); + + var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full"); + + if (key == null) + { + return false; + } + + var value = key.GetValue("Version"); + + if (value != null && value is string versionString) + { + var installedVersion = new Version(versionString); + + return installedVersion > minRequiredVersion; + } + + return false; + } + + public DependencyCheckTask() : base("Dependency Checks", true) + { + } + + GenericResult getResult(bool net472Check, bool netCoreCheck) => + (net472Check, netCoreCheck) switch + { + (true, true) => GenericResult.FromSuccess("Dependencies already installed"), + (false, true) => GenericResult.FromWarning(".Net Framework 472 not found.\nCheck SPT release page for requirements\nhttps://hub.sp-tarkov.com/files/file/16-spt-aki/"), + (true, false) => GenericResult.FromWarning(".Net Runtime Desktop 6 not found.\nCheck SPT release page for requirements\nhttps://hub.sp-tarkov.com/files/file/16-spt-aki/"), + (false, false) => GenericResult.FromWarning("Required dependencies not found.\nCheck SPT release page for requirements\nhttps://hub.sp-tarkov.com/files/file/16-spt-aki/") + }; + + public override Task RunAsync() + { + SetStatus("Checking for net framework"); + + var net472Check = CheckNet472Installed(); + + SetStatus("Checking for net core"); + + var netCoreCheck = CheckNetCore6Installed(); + + return Task.FromResult(getResult(net472Check, netCoreCheck)); + } + } +}