Add global using directives and free space pre-check
Global System and System.IO usages have been replaced with global usings in GlobalUsings.cs for improved code readability. Alongside, a FreeSpacePreCheck has been added in FreeSpacePreCheck.cs to ensure enough drive space is available before installation. This check was initially taking place in InitializationTask.cs which has been removed for better separation of concerns. The PreCheckViewModel visibility is now dependent on the success status of PreChecks, enhancing user experience.
This commit is contained in:
parent
68e50cf5e5
commit
d3767a0344
3
SPTInstaller/GlobalUsings.cs
Normal file
3
SPTInstaller/GlobalUsings.cs
Normal file
@ -0,0 +1,3 @@
|
||||
// Global using directives
|
||||
global using System;
|
||||
global using System.IO;
|
@ -1,46 +1,29 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using Serilog;
|
||||
using SPTInstaller.Models;
|
||||
|
||||
namespace SPTInstaller.Helpers
|
||||
namespace SPTInstaller.Helpers;
|
||||
|
||||
public static class DirectorySizeHelper
|
||||
{
|
||||
public static class DirectorySizeHelper
|
||||
public static bool CheckAvailableSize(string eftSourceDirPath, string installTargetDirPath)
|
||||
{
|
||||
public static Result CheckAvailableSize(string eftSourceDirPath, string installTargetDirPath)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var eftSourceDirectoryInfo = new DirectoryInfo(eftSourceDirPath);
|
||||
var installTargetDirectoryInfo = new DirectoryInfo(installTargetDirPath);
|
||||
var eftSourceDirectoryInfo = new DirectoryInfo(eftSourceDirPath);
|
||||
var installTargetDirectoryInfo = new DirectoryInfo(installTargetDirPath);
|
||||
|
||||
var eftSourceDirSize = GetSizeOfDirectory(eftSourceDirectoryInfo);
|
||||
var availableSize = DriveInfo.GetDrives().FirstOrDefault(d => d.Name == installTargetDirectoryInfo.Root.Name)?.AvailableFreeSpace ?? 0;
|
||||
var eftSourceDirSize = GetSizeOfDirectory(eftSourceDirectoryInfo);
|
||||
var availableSize = DriveInfo.GetDrives().FirstOrDefault(d => d.Name == installTargetDirectoryInfo.Root.Name)?.AvailableFreeSpace ?? 0;
|
||||
|
||||
if (eftSourceDirSize > availableSize)
|
||||
{
|
||||
return Result.FromError($"Not enough space on drive {installTargetDirectoryInfo.Root.Name}.\n\nRequired: {FormatFileSize(eftSourceDirSize)}\nAvailable: {FormatFileSize(availableSize)}");
|
||||
}
|
||||
|
||||
return Result.FromSuccess();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error while checking available size");
|
||||
|
||||
return Result.FromError(ex.Message);
|
||||
}
|
||||
return eftSourceDirSize < availableSize;
|
||||
}
|
||||
|
||||
private static long GetSizeOfDirectory(DirectoryInfo sourceDir) => sourceDir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length);
|
||||
|
||||
private static string FormatFileSize(long bytes)
|
||||
catch (Exception ex)
|
||||
{
|
||||
const int unit = 1024;
|
||||
var exp = (int)(Math.Log(bytes) / Math.Log(unit));
|
||||
Log.Error(ex, "Error while checking available size");
|
||||
|
||||
return $"{bytes / Math.Pow(unit, exp):F2} {"KMGTPE"[exp - 1]}B";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static long GetSizeOfDirectory(DirectoryInfo sourceDir) => sourceDir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length);
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
using SPTInstaller.Interfaces;
|
||||
using SPTInstaller.Models;
|
||||
using System.Threading.Tasks;
|
||||
using SPTInstaller.Helpers;
|
||||
|
||||
namespace SPTInstaller.Installer_Tasks
|
||||
{
|
||||
@ -28,12 +27,6 @@ namespace SPTInstaller.Installer_Tasks
|
||||
|
||||
SetStatus(null, $"Installed EFT Game Path: {FileHelper.GetRedactedPath(_data.OriginalGamePath)}");
|
||||
|
||||
var directorySizeCheckResult = DirectorySizeHelper.CheckAvailableSize(_data.OriginalGamePath, _data.TargetInstallPath);
|
||||
if (!directorySizeCheckResult.Succeeded)
|
||||
{
|
||||
return Result.FromError(directorySizeCheckResult.Message);
|
||||
}
|
||||
|
||||
var result = PreCheckHelper.DetectOriginalGameVersion(_data.OriginalGamePath);
|
||||
|
||||
if (!result.Succeeded)
|
||||
|
25
SPTInstaller/Installer Tasks/PreChecks/FreeSpacePreCheck.cs
Normal file
25
SPTInstaller/Installer Tasks/PreChecks/FreeSpacePreCheck.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System.Threading.Tasks;
|
||||
using SPTInstaller.Helpers;
|
||||
using SPTInstaller.Models;
|
||||
|
||||
namespace SPTInstaller.Installer_Tasks.PreChecks;
|
||||
|
||||
public class FreeSpacePreCheck : PreCheckBase
|
||||
{
|
||||
private readonly InternalData _internalData;
|
||||
|
||||
public FreeSpacePreCheck(InternalData internalData) : base("Free Space", true)
|
||||
{
|
||||
_internalData = internalData;
|
||||
}
|
||||
|
||||
public override async Task<bool> CheckOperation()
|
||||
{
|
||||
if (_internalData.OriginalGamePath is null || _internalData.TargetInstallPath is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return DirectorySizeHelper.CheckAvailableSize(_internalData.OriginalGamePath, _internalData.TargetInstallPath);
|
||||
}
|
||||
}
|
@ -8,12 +8,12 @@ namespace SPTInstaller.Models
|
||||
/// <summary>
|
||||
/// The folder to install SPT into
|
||||
/// </summary>
|
||||
public string TargetInstallPath { get; set; }
|
||||
public string? TargetInstallPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The orginal EFT game path
|
||||
/// </summary>
|
||||
public string OriginalGamePath { get; set; }
|
||||
public string? OriginalGamePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The original EFT game version
|
||||
|
@ -9,8 +9,6 @@ using SPTInstaller.Installer_Tasks;
|
||||
using SPTInstaller.Installer_Tasks.PreChecks;
|
||||
using SPTInstaller.Interfaces;
|
||||
using SPTInstaller.Models;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
@ -35,8 +33,9 @@ namespace SPTInstaller
|
||||
ServiceHelper.Register<InternalData>();
|
||||
ServiceHelper.Register<PreCheckBase, NetFramework472PreCheck>();
|
||||
ServiceHelper.Register<PreCheckBase, NetCore6PreCheck>();
|
||||
ServiceHelper.Register<PreCheckBase, FreeSpacePreCheck>();
|
||||
#if !TEST
|
||||
string logPath = Path.Join(Environment.CurrentDirectory, "spt-aki-installer_.log");
|
||||
var logPath = Path.Join(Environment.CurrentDirectory, "spt-aki-installer_.log");
|
||||
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
|
@ -1,59 +1,48 @@
|
||||
using ReactiveUI;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using ReactiveUI;
|
||||
using SPTInstaller.Aki.Helper;
|
||||
using SPTInstaller.Controllers;
|
||||
using SPTInstaller.Helpers;
|
||||
using SPTInstaller.Models;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace SPTInstaller.ViewModels
|
||||
namespace SPTInstaller.ViewModels;
|
||||
|
||||
public class PreChecksViewModel : ViewModelBase
|
||||
{
|
||||
public class PreChecksViewModel : ViewModelBase
|
||||
private string _installPath;
|
||||
|
||||
public ObservableCollection<PreCheckBase> PreChecks { get; set; } = new(ServiceHelper.GetAll<PreCheckBase>());
|
||||
public ICommand StartInstallCommand { get; set; }
|
||||
public bool PreCheckSucceeded { get; set; }
|
||||
public string InstallPath
|
||||
{
|
||||
private string _InstallPath;
|
||||
public string InstallPath
|
||||
{
|
||||
get => _InstallPath;
|
||||
set => this.RaiseAndSetIfChanged(ref _InstallPath, value);
|
||||
}
|
||||
|
||||
ObservableCollection<PreCheckBase> PreChecks { get; set; }
|
||||
= new ObservableCollection<PreCheckBase>(ServiceHelper.GetAll<PreCheckBase>());
|
||||
|
||||
ICommand StartInstallCommand { get; set; }
|
||||
|
||||
public PreChecksViewModel(IScreen host) : base(host)
|
||||
{
|
||||
var data = ServiceHelper.Get<InternalData>();
|
||||
var installer = ServiceHelper.Get<InstallController>();
|
||||
|
||||
if(data == null || installer == null)
|
||||
{
|
||||
NavigateTo(new MessageViewModel(HostScreen, Result.FromError("Failed to get required service for prechecks")));
|
||||
return;
|
||||
}
|
||||
|
||||
data.TargetInstallPath = Environment.CurrentDirectory;
|
||||
|
||||
InstallPath = data.TargetInstallPath;
|
||||
|
||||
StartInstallCommand = ReactiveCommand.Create(() =>
|
||||
{
|
||||
NavigateTo(new InstallViewModel(HostScreen));
|
||||
});
|
||||
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var result = await installer.RunPreChecks();
|
||||
|
||||
if(!result.Succeeded)
|
||||
{
|
||||
//if a required precheck fails, abort to message view
|
||||
NavigateTo(new MessageViewModel(HostScreen ,result));
|
||||
}
|
||||
});
|
||||
}
|
||||
get => _installPath;
|
||||
set => this.RaiseAndSetIfChanged(ref _installPath, value);
|
||||
}
|
||||
}
|
||||
|
||||
public PreChecksViewModel(IScreen host) : base(host)
|
||||
{
|
||||
var data = ServiceHelper.Get<InternalData?>();
|
||||
var installer = ServiceHelper.Get<InstallController?>();
|
||||
|
||||
if (data == null || installer == null)
|
||||
{
|
||||
NavigateTo(new MessageViewModel(HostScreen, Result.FromError("Failed to get required service for prechecks")));
|
||||
return;
|
||||
}
|
||||
|
||||
data.OriginalGamePath = PreCheckHelper.DetectOriginalGamePath();
|
||||
data.TargetInstallPath = Environment.CurrentDirectory;
|
||||
InstallPath = data.TargetInstallPath;
|
||||
|
||||
StartInstallCommand = ReactiveCommand.Create(() => NavigateTo(new InstallViewModel(HostScreen)));
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var result = await installer.RunPreChecks();
|
||||
PreCheckSucceeded = result.Succeeded;
|
||||
});
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@
|
||||
Margin="10"
|
||||
FontSize="15" FontWeight="SemiBold"
|
||||
Classes="yellow"
|
||||
IsVisible="{Binding PreCheckSucceeded}"
|
||||
Command="{Binding StartInstallCommand}"
|
||||
/>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user