File scoped namespace program.cs

Also trim the Version for parsing
This commit is contained in:
Kurt 2023-01-21 23:32:18 -08:00
parent dfcc22c453
commit 1baba56a4f
2 changed files with 136 additions and 128 deletions

View File

@ -21,8 +21,6 @@ namespace PKHeX.WinForms;
public partial class Main : Form
{
private static readonly Version CurrentProgramVersion = Version.Parse(Application.ProductVersion);
public Main()
{
string[] args = Environment.GetCommandLineArgs();
@ -201,7 +199,7 @@ private void FormLoadCheckForUpdates()
Debug.WriteLine($"Exception while checking for latest version: {ex}");
return;
}
if (latestVersion is null || latestVersion <= CurrentProgramVersion)
if (latestVersion is null || latestVersion <= Program.CurrentVersion)
return;
while (!IsHandleCreated) // Wait for form to be ready
@ -227,9 +225,9 @@ private static void FormLoadConfig(out bool BAKprompt, out bool showChangelog)
if (Settings.Startup.Version.Length > 0 && Settings.Startup.ShowChangelogOnUpdate) // already run on system
{
bool parsed = Version.TryParse(Settings.Startup.Version, out var lastrev);
showChangelog = parsed && lastrev < CurrentProgramVersion;
showChangelog = parsed && lastrev < Program.CurrentVersion;
}
Settings.Startup.Version = CurrentProgramVersion.ToString(); // set current ver so this doesn't happen until the user updates next time
Settings.Startup.Version = Program.CurrentVersion.ToString(); // set current ver so this doesn't happen until the user updates next time
// BAK Prompt
if (!Settings.Backup.BAKPrompt)
@ -271,7 +269,7 @@ private void FormLoadPlugins()
return;
}
foreach (var p in Plugins.OrderBy(z => z.Priority))
p.Initialize(C_SAV, PKME_Tabs, menuStrip1, CurrentProgramVersion);
p.Initialize(C_SAV, PKME_Tabs, menuStrip1, Program.CurrentVersion);
}
// Main Menu Strip UI Functions
@ -807,7 +805,7 @@ private static string GetProgramTitle()
var date = File.GetLastWriteTime(Environment.ProcessPath!);
string version = $"d-{date:yyyyMMdd}";
#else
var ver = CurrentProgramVersion;
var ver = Program.CurrentVersion;
string version = $"{2000+ver.Major:00}{ver.Minor:00}{ver.Build:00}";
#endif
return $"PKH{(HaX ? "a" : "e")}X ({version})";

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using PKHeX.Core;
@ -9,131 +9,141 @@
using System.Threading;
#endif
namespace PKHeX.WinForms
namespace PKHeX.WinForms;
internal static class Program
{
internal static class Program
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
#if !DEBUG
// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += UIThreadException;
// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += UIThreadException;
// Set the unhandled exception mode to force all Windows Forms errors to go through our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Set the unhandled exception mode to force all Windows Forms errors to go through our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
#endif
// Run the application
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var splash = new SplashScreen();
new Task(() => splash.ShowDialog()).Start();
new Task(() => EncounterEvent.RefreshMGDB(WinForms.Main.MGDatabasePath)).Start();
var main = new Main();
splash.Invoke(splash.ForceClose);
Application.Run(main);
}
#if !DEBUG
private static void Error(string msg) => MessageBox.Show(msg, "PKHeX Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
// Handle the UI exceptions by showing a dialog box, and asking the user whether or not they wish to abort execution.
private static void UIThreadException(object sender, ThreadExceptionEventArgs t)
{
DialogResult result = DialogResult.Cancel;
try
{
result = ErrorWindow.ShowErrorDialog("An unhandled exception has occurred.\nYou can continue running PKHeX, but please report this error.", t.Exception, true);
}
catch (Exception reportingException)
{
HandleReportingException(t.Exception, reportingException);
}
// Exits the program when the user clicks Abort.
if (result == DialogResult.Abort)
Application.Exit();
}
// Handle the UI exceptions by showing a dialog box, and asking the user whether
// or not they wish to abort execution.
// NOTE: This exception cannot be kept from terminating the application - it can only
// log the event, and inform the user about it.
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
try
{
if (IsOldPkhexCorePresent(ex))
{
Error("You have upgraded PKHeX incorrectly. Please delete PKHeX.Core.dll.");
}
else if (ex != null)
{
ErrorWindow.ShowErrorDialog("An unhandled exception has occurred.\nPKHeX must now close.", ex, false);
}
else
{
Error("A fatal non-UI error has occurred in PKHeX, and the details could not be displayed. Please report this to the author.");
}
}
catch (Exception reportingException)
{
HandleReportingException(ex, reportingException);
}
}
private static void HandleReportingException(Exception? ex, Exception reportingException)
{
if (reportingException is FileNotFoundException x && x.FileName?.StartsWith("PKHeX.Core") == true)
{
Error("Could not locate PKHeX.Core.dll. Make sure you're running PKHeX together with its code library. Usually caused when all files are not extracted.");
return;
}
try
{
Error("A fatal non-UI error has occurred in PKHeX, and there was a problem displaying the details. Please report this to the author.");
EmergencyErrorLog(ex, reportingException);
}
finally
{
Application.Exit();
}
}
/// <summary>
/// Attempt to log exceptions to a file when there's an error displaying exception details.
/// </summary>
/// <param name="originalException"></param>
/// <param name="errorHandlingException"></param>
private static bool EmergencyErrorLog(Exception? originalException, Exception errorHandlingException)
{
try
{
// Not using a string builder because something's very wrong, and we don't want to make things worse
var message = (originalException?.ToString() ?? "null first exception") + Environment.NewLine + errorHandlingException;
File.WriteAllText($"PKHeX_Error_Report {DateTime.Now:yyyyMMddHHmmss}.txt", message);
}
catch (Exception)
{
// We've failed to save the error details twice now. There's nothing else we can do.
return false;
}
return true;
}
private static bool IsOldPkhexCorePresent(Exception? ex)
{
return ex is MissingMethodException or TypeLoadException or TypeInitializationException
&& File.Exists("PKHeX.Core.dll")
&& AssemblyName.GetAssemblyName("PKHeX.Core.dll").Version < Assembly.GetExecutingAssembly().GetName().Version;
}
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
#endif
// Run the application
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var splash = new SplashScreen();
new Task(() => splash.ShowDialog()).Start();
new Task(() => EncounterEvent.RefreshMGDB(WinForms.Main.MGDatabasePath)).Start();
var main = new Main();
splash.Invoke(splash.ForceClose);
Application.Run(main);
}
// Pipelines build can sometimes tack on text to the version code. Strip it out.
public static readonly Version CurrentVersion = Version.Parse(GetSaneVersionTag(Application.ProductVersion));
private static ReadOnlySpan<char> GetSaneVersionTag(ReadOnlySpan<char> productVersion)
{
var firstDash = productVersion.IndexOf('-');
if (firstDash == -1)
return productVersion;
return productVersion[..firstDash];
}
#if !DEBUG
private static void Error(string msg) => MessageBox.Show(msg, "PKHeX Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
// Handle the UI exceptions by showing a dialog box, and asking the user whether or not they wish to abort execution.
private static void UIThreadException(object sender, ThreadExceptionEventArgs t)
{
DialogResult result = DialogResult.Cancel;
try
{
result = ErrorWindow.ShowErrorDialog("An unhandled exception has occurred.\nYou can continue running PKHeX, but please report this error.", t.Exception, true);
}
catch (Exception reportingException)
{
HandleReportingException(t.Exception, reportingException);
}
// Exits the program when the user clicks Abort.
if (result == DialogResult.Abort)
Application.Exit();
}
// Handle the UI exceptions by showing a dialog box, and asking the user whether
// or not they wish to abort execution.
// NOTE: This exception cannot be kept from terminating the application - it can only
// log the event, and inform the user about it.
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
try
{
if (IsOldPkhexCorePresent(ex))
{
Error("You have upgraded PKHeX incorrectly. Please delete PKHeX.Core.dll.");
}
else if (ex != null)
{
ErrorWindow.ShowErrorDialog("An unhandled exception has occurred.\nPKHeX must now close.", ex, false);
}
else
{
Error("A fatal non-UI error has occurred in PKHeX, and the details could not be displayed. Please report this to the author.");
}
}
catch (Exception reportingException)
{
HandleReportingException(ex, reportingException);
}
}
private static void HandleReportingException(Exception? ex, Exception reportingException)
{
if (reportingException is FileNotFoundException x && x.FileName?.StartsWith("PKHeX.Core") == true)
{
Error("Could not locate PKHeX.Core.dll. Make sure you're running PKHeX together with its code library. Usually caused when all files are not extracted.");
return;
}
try
{
Error("A fatal non-UI error has occurred in PKHeX, and there was a problem displaying the details. Please report this to the author.");
EmergencyErrorLog(ex, reportingException);
}
finally
{
Application.Exit();
}
}
/// <summary>
/// Attempt to log exceptions to a file when there's an error displaying exception details.
/// </summary>
/// <param name="originalException"></param>
/// <param name="errorHandlingException"></param>
private static bool EmergencyErrorLog(Exception? originalException, Exception errorHandlingException)
{
try
{
// Not using a string builder because something's very wrong, and we don't want to make things worse
var message = (originalException?.ToString() ?? "null first exception") + Environment.NewLine + errorHandlingException;
File.WriteAllText($"PKHeX_Error_Report {DateTime.Now:yyyyMMddHHmmss}.txt", message);
}
catch (Exception)
{
// We've failed to save the error details twice now. There's nothing else we can do.
return false;
}
return true;
}
private static bool IsOldPkhexCorePresent(Exception? ex)
{
return ex is MissingMethodException or TypeLoadException or TypeInitializationException
&& File.Exists("PKHeX.Core.dll")
&& AssemblyName.GetAssemblyName("PKHeX.Core.dll").Version < CurrentVersion;
}
#endif
}