mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 18:11:27 -07:00
Sanity check install location/drive (#474)
moved to its own class for better flow control
This commit is contained in:
parent
ba45bf46b4
commit
894587554c
@ -22,7 +22,8 @@ namespace Bloxstrap
|
|||||||
public static bool ShouldSaveConfigs { get; set; } = false;
|
public static bool ShouldSaveConfigs { get; set; } = false;
|
||||||
|
|
||||||
public static bool IsSetupComplete { get; set; } = true;
|
public static bool IsSetupComplete { get; set; } = true;
|
||||||
public static bool IsFirstRun { get; private set; } = true;
|
public static bool IsFirstRun { get; set; } = true;
|
||||||
|
|
||||||
public static bool IsQuiet { get; private set; } = false;
|
public static bool IsQuiet { get; private set; } = false;
|
||||||
public static bool IsUninstall { get; private set; } = false;
|
public static bool IsUninstall { get; private set; } = false;
|
||||||
public static bool IsNoLaunch { get; private set; } = false;
|
public static bool IsNoLaunch { get; private set; } = false;
|
||||||
@ -149,11 +150,12 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
if (!IsMenuLaunch)
|
if (!IsMenuLaunch)
|
||||||
{
|
{
|
||||||
Logger.WriteLine(LOG_IDENT, "Performing connectivity check");
|
Logger.WriteLine(LOG_IDENT, "Performing connectivity check...");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpClient.GetAsync("https://detectportal.firefox.com").Wait();
|
HttpClient.GetAsync("https://detectportal.firefox.com").Wait();
|
||||||
|
Logger.WriteLine(LOG_IDENT, "Connectivity check finished");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -173,41 +175,9 @@ namespace Bloxstrap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using (var checker = new InstallChecker())
|
||||||
// check if installed
|
|
||||||
using (RegistryKey? registryKey = Registry.CurrentUser.OpenSubKey($@"Software\{ProjectName}"))
|
|
||||||
{
|
{
|
||||||
string? installLocation = null;
|
checker.Check();
|
||||||
|
|
||||||
if (registryKey is not null)
|
|
||||||
installLocation = (string?)registryKey.GetValue("InstallLocation");
|
|
||||||
|
|
||||||
if (registryKey is null || installLocation is null)
|
|
||||||
{
|
|
||||||
Logger.WriteLine(LOG_IDENT, "Running first-time install");
|
|
||||||
|
|
||||||
BaseDirectory = Path.Combine(Paths.LocalAppData, ProjectName);
|
|
||||||
Logger.Initialize(true);
|
|
||||||
|
|
||||||
if (!IsQuiet)
|
|
||||||
{
|
|
||||||
IsSetupComplete = false;
|
|
||||||
FastFlags.Load();
|
|
||||||
Controls.ShowMenu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IsFirstRun = false;
|
|
||||||
BaseDirectory = installLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// exit if we don't click the install button on installation
|
|
||||||
if (!IsSetupComplete)
|
|
||||||
{
|
|
||||||
Logger.WriteLine(LOG_IDENT, "Installation cancelled!");
|
|
||||||
Terminate(ErrorCode.ERROR_CANCELLED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths.Initialize(BaseDirectory);
|
Paths.Initialize(BaseDirectory);
|
||||||
@ -234,7 +204,7 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (!IsUninstall && !IsFirstRun)
|
if (!IsUninstall && !IsFirstRun)
|
||||||
Updater.CheckInstalledVersion();
|
InstallChecker.CheckUpgrade();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string commandLine = "";
|
string commandLine = "";
|
||||||
|
230
Bloxstrap/InstallChecker.cs
Normal file
230
Bloxstrap/InstallChecker.cs
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
namespace Bloxstrap
|
||||||
|
{
|
||||||
|
internal class InstallChecker : IDisposable
|
||||||
|
{
|
||||||
|
private RegistryKey? _registryKey;
|
||||||
|
private string? _installLocation;
|
||||||
|
|
||||||
|
internal InstallChecker()
|
||||||
|
{
|
||||||
|
_registryKey = Registry.CurrentUser.OpenSubKey($"Software\\{App.ProjectName}", true);
|
||||||
|
|
||||||
|
if (_registryKey is not null)
|
||||||
|
_installLocation = (string?)_registryKey.GetValue("InstallLocation");
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Check()
|
||||||
|
{
|
||||||
|
const string LOG_IDENT = "InstallChecker::Check";
|
||||||
|
|
||||||
|
if (_registryKey is null || _installLocation is null)
|
||||||
|
{
|
||||||
|
if (!File.Exists("Settings.json") || !File.Exists("State.json"))
|
||||||
|
{
|
||||||
|
FirstTimeRun();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_installLocation = Path.GetDirectoryName(Paths.Process)!;
|
||||||
|
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, $"Registry key is likely malformed. Setting install location as '{_installLocation}'");
|
||||||
|
|
||||||
|
if (_registryKey is null)
|
||||||
|
_registryKey = Registry.CurrentUser.CreateSubKey($"Software\\{App.ProjectName}");
|
||||||
|
|
||||||
|
_registryKey.SetValue("InstallLocation", _installLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if drive that bloxstrap was installed to was removed from system, or had its drive letter changed
|
||||||
|
|
||||||
|
if (!Directory.Exists(_installLocation))
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Could not find install location. Checking if drive has changed...");
|
||||||
|
|
||||||
|
bool driveExists = false;
|
||||||
|
string driveName = _installLocation[..3];
|
||||||
|
string? newDriveName = null;
|
||||||
|
|
||||||
|
foreach (var drive in DriveInfo.GetDrives())
|
||||||
|
{
|
||||||
|
if (drive.Name == driveName)
|
||||||
|
driveExists = true;
|
||||||
|
else if (Directory.Exists(_installLocation.Replace(driveName, drive.Name)))
|
||||||
|
newDriveName = drive.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newDriveName is not null)
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, $"Drive has changed from {driveName} to {newDriveName}");
|
||||||
|
|
||||||
|
Controls.ShowMessageBox(
|
||||||
|
$"{App.ProjectName} has detected a drive letter change and has reconfigured its install location from the {driveName} drive to the {newDriveName} drive.\n" +
|
||||||
|
"\n" +
|
||||||
|
$"While {App.ProjectName} will continue to work, it's recommended that you change the drive leter back to its original value as other installed applications can experience similar issues.",
|
||||||
|
MessageBoxImage.Warning,
|
||||||
|
MessageBoxButton.OK
|
||||||
|
);
|
||||||
|
|
||||||
|
_installLocation = _installLocation.Replace(driveName, newDriveName);
|
||||||
|
_registryKey.SetValue("InstallLocation", _installLocation);
|
||||||
|
}
|
||||||
|
else if (!driveExists)
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, $"Drive {driveName} does not exist anymore, and has likely been removed");
|
||||||
|
|
||||||
|
var result = Controls.ShowMessageBox(
|
||||||
|
$"{App.ProjectName} was originally installed to the {driveName} drive, but it appears to no longer be present. Would you like to continue and carry out a fresh install?",
|
||||||
|
MessageBoxImage.Warning,
|
||||||
|
MessageBoxButton.OKCancel
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != MessageBoxResult.OK)
|
||||||
|
App.Terminate();
|
||||||
|
|
||||||
|
FirstTimeRun();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Drive has not changed, folder was likely moved or deleted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
App.BaseDirectory = _installLocation;
|
||||||
|
App.IsFirstRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_registryKey?.Dispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FirstTimeRun()
|
||||||
|
{
|
||||||
|
const string LOG_IDENT = "InstallChecker::FirstTimeRun";
|
||||||
|
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Running first-time install");
|
||||||
|
|
||||||
|
App.BaseDirectory = Path.Combine(Paths.LocalAppData, App.ProjectName);
|
||||||
|
App.Logger.Initialize(true);
|
||||||
|
|
||||||
|
if (App.IsQuiet)
|
||||||
|
return;
|
||||||
|
|
||||||
|
App.IsSetupComplete = false;
|
||||||
|
|
||||||
|
App.FastFlags.Load();
|
||||||
|
Controls.ShowMenu();
|
||||||
|
|
||||||
|
// exit if we don't click the install button on installation
|
||||||
|
if (App.IsSetupComplete)
|
||||||
|
return;
|
||||||
|
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Installation cancelled!");
|
||||||
|
App.Terminate(ErrorCode.ERROR_CANCELLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void CheckUpgrade()
|
||||||
|
{
|
||||||
|
const string LOG_IDENT = "InstallChecker::CheckUpgrade";
|
||||||
|
|
||||||
|
if (!File.Exists(Paths.Application) || Paths.Process == Paths.Application)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 2.0.0 downloads updates to <BaseFolder>/Updates so lol
|
||||||
|
bool isAutoUpgrade = Paths.Process.StartsWith(Path.Combine(Paths.Base, "Updates")) || Paths.Process.StartsWith(Path.Combine(Paths.LocalAppData, "Temp"));
|
||||||
|
|
||||||
|
FileVersionInfo existingVersionInfo = FileVersionInfo.GetVersionInfo(Paths.Application);
|
||||||
|
FileVersionInfo currentVersionInfo = FileVersionInfo.GetVersionInfo(Paths.Process);
|
||||||
|
|
||||||
|
if (MD5Hash.FromFile(Paths.Process) == MD5Hash.FromFile(Paths.Application))
|
||||||
|
return;
|
||||||
|
|
||||||
|
MessageBoxResult result;
|
||||||
|
|
||||||
|
// silently upgrade version if the command line flag is set or if we're launching from an auto update
|
||||||
|
if (App.IsUpgrade || isAutoUpgrade)
|
||||||
|
{
|
||||||
|
result = MessageBoxResult.Yes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = Controls.ShowMessageBox(
|
||||||
|
$"The version of {App.ProjectName} you've launched is different to the version you currently have installed.\nWould you like to upgrade your currently installed version?",
|
||||||
|
MessageBoxImage.Question,
|
||||||
|
MessageBoxButton.YesNo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != MessageBoxResult.Yes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// yes, this is EXTREMELY hacky, but the updater process that launched the
|
||||||
|
// new version may still be open and so we have to wait for it to close
|
||||||
|
int attempts = 0;
|
||||||
|
while (attempts < 10)
|
||||||
|
{
|
||||||
|
attempts++;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(Paths.Application);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
if (attempts == 1)
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Waiting for write permissions to update version");
|
||||||
|
|
||||||
|
Thread.Sleep(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attempts == 10)
|
||||||
|
{
|
||||||
|
App.Logger.WriteLine(LOG_IDENT, "Failed to update! (Could not get write permissions after 5 seconds)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Copy(Paths.Process, Paths.Application);
|
||||||
|
|
||||||
|
Bootstrapper.Register();
|
||||||
|
|
||||||
|
// update migrations
|
||||||
|
|
||||||
|
if (App.BuildMetadata.CommitRef.StartsWith("tag") && existingVersionInfo.ProductVersion == "2.4.0")
|
||||||
|
{
|
||||||
|
App.FastFlags.SetValue("DFFlagDisableDPIScale", null);
|
||||||
|
App.FastFlags.SetValue("DFFlagVariableDPIScale2", null);
|
||||||
|
App.FastFlags.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAutoUpgrade)
|
||||||
|
{
|
||||||
|
App.NotifyIcon?.ShowAlert(
|
||||||
|
$"{App.ProjectName} has been upgraded to v{currentVersionInfo.ProductVersion}",
|
||||||
|
"See what's new in this version",
|
||||||
|
30,
|
||||||
|
(_, _) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/releases/tag/v{currentVersionInfo.ProductVersion}")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (!App.IsQuiet)
|
||||||
|
{
|
||||||
|
Controls.ShowMessageBox(
|
||||||
|
$"{App.ProjectName} has been upgraded to v{currentVersionInfo.ProductVersion}",
|
||||||
|
MessageBoxImage.Information,
|
||||||
|
MessageBoxButton.OK
|
||||||
|
);
|
||||||
|
|
||||||
|
Controls.ShowMenu();
|
||||||
|
|
||||||
|
App.Terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,105 +0,0 @@
|
|||||||
using System.Windows;
|
|
||||||
|
|
||||||
namespace Bloxstrap
|
|
||||||
{
|
|
||||||
public class Updater
|
|
||||||
{
|
|
||||||
public static void CheckInstalledVersion()
|
|
||||||
{
|
|
||||||
const string LOG_IDENT = "Updater::CheckInstalledVersion";
|
|
||||||
|
|
||||||
if (!File.Exists(Paths.Application) || Paths.Process == Paths.Application)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 2.0.0 downloads updates to <BaseFolder>/Updates so lol
|
|
||||||
bool isAutoUpgrade = Paths.Process.StartsWith(Path.Combine(Paths.Base, "Updates")) || Paths.Process.StartsWith(Path.Combine(Paths.LocalAppData, "Temp"));
|
|
||||||
|
|
||||||
FileVersionInfo existingVersionInfo = FileVersionInfo.GetVersionInfo(Paths.Application);
|
|
||||||
FileVersionInfo currentVersionInfo = FileVersionInfo.GetVersionInfo(Paths.Process);
|
|
||||||
|
|
||||||
if (MD5Hash.FromFile(Paths.Process) == MD5Hash.FromFile(Paths.Application))
|
|
||||||
return;
|
|
||||||
|
|
||||||
MessageBoxResult result;
|
|
||||||
|
|
||||||
// silently upgrade version if the command line flag is set or if we're launching from an auto update
|
|
||||||
if (App.IsUpgrade || isAutoUpgrade)
|
|
||||||
{
|
|
||||||
result = MessageBoxResult.Yes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = Controls.ShowMessageBox(
|
|
||||||
$"The version of {App.ProjectName} you've launched is different to the version you currently have installed.\nWould you like to upgrade your currently installed version?",
|
|
||||||
MessageBoxImage.Question,
|
|
||||||
MessageBoxButton.YesNo
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != MessageBoxResult.Yes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// yes, this is EXTREMELY hacky, but the updater process that launched the
|
|
||||||
// new version may still be open and so we have to wait for it to close
|
|
||||||
int attempts = 0;
|
|
||||||
while (attempts < 10)
|
|
||||||
{
|
|
||||||
attempts++;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Delete(Paths.Application);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
if (attempts == 1)
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Waiting for write permissions to update version");
|
|
||||||
|
|
||||||
Thread.Sleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attempts == 10)
|
|
||||||
{
|
|
||||||
App.Logger.WriteLine(LOG_IDENT, "Failed to update! (Could not get write permissions after 5 seconds)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File.Copy(Paths.Process, Paths.Application);
|
|
||||||
|
|
||||||
Bootstrapper.Register();
|
|
||||||
|
|
||||||
// update migrations
|
|
||||||
|
|
||||||
if (App.BuildMetadata.CommitRef.StartsWith("tag") && existingVersionInfo.ProductVersion == "2.4.0")
|
|
||||||
{
|
|
||||||
App.FastFlags.SetValue("DFFlagDisableDPIScale", null);
|
|
||||||
App.FastFlags.SetValue("DFFlagVariableDPIScale2", null);
|
|
||||||
App.FastFlags.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isAutoUpgrade)
|
|
||||||
{
|
|
||||||
App.NotifyIcon?.ShowAlert(
|
|
||||||
$"Bloxstrap has been upgraded to v{currentVersionInfo.ProductVersion}",
|
|
||||||
"See what's new in this version",
|
|
||||||
30,
|
|
||||||
(_, _) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/releases/tag/v{currentVersionInfo.ProductVersion}")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (!App.IsQuiet)
|
|
||||||
{
|
|
||||||
Controls.ShowMessageBox(
|
|
||||||
$"{App.ProjectName} has been upgraded to v{currentVersionInfo.ProductVersion}",
|
|
||||||
MessageBoxImage.Information,
|
|
||||||
MessageBoxButton.OK
|
|
||||||
);
|
|
||||||
|
|
||||||
Controls.ShowMenu();
|
|
||||||
|
|
||||||
App.Terminate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user