2019-10-17 03:52:09 +00:00
using System ;
2020-10-29 00:27:11 +00:00
using System.Threading.Tasks ;
2017-11-24 20:03:57 +00:00
using System.Windows.Forms ;
2020-10-29 00:27:11 +00:00
using PKHeX.Core ;
2017-11-24 20:03:57 +00:00
#if ! DEBUG
2020-02-02 18:20:51 +00:00
using System.Reflection ;
2017-01-28 17:48:00 +00:00
using System.IO ;
2016-08-22 01:05:41 +00:00
using System.Threading ;
2017-11-24 20:03:57 +00:00
#endif
2014-06-28 21:22:05 +00:00
2017-01-08 07:54:09 +00:00
namespace PKHeX.WinForms
2014-06-28 21:22:05 +00:00
{
2016-07-09 01:14:15 +00:00
internal static class Program
2014-06-28 21:22:05 +00:00
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
2016-07-09 01:14:15 +00:00
private static void Main ( )
2014-06-28 21:22:05 +00:00
{
2017-01-15 00:41:27 +00:00
#if ! DEBUG
2016-08-22 01:05:41 +00:00
// Add the event handler for handling UI thread exceptions to the event.
2017-01-08 07:54:09 +00:00
Application . ThreadException + = UIThreadException ;
2016-08-22 01:05:41 +00:00
// Set the unhandled exception mode to force all Windows Forms errors to go through our handler.
Application . SetUnhandledExceptionMode ( UnhandledExceptionMode . CatchException ) ;
2018-05-12 19:28:48 +00:00
// Add the event handler for handling non-UI thread exceptions to the event.
2017-01-08 07:54:09 +00:00
AppDomain . CurrentDomain . UnhandledException + = CurrentDomain_UnhandledException ;
2017-01-15 00:41:27 +00:00
#endif
2016-08-22 01:05:41 +00:00
// Run the application
2014-06-28 21:22:05 +00:00
Application . EnableVisualStyles ( ) ;
Application . SetCompatibleTextRenderingDefault ( false ) ;
2020-10-29 00:27:11 +00:00
var splash = new SplashScreen ( ) ;
new Task ( ( ) = > splash . ShowDialog ( ) ) . Start ( ) ;
new Task ( ( ) = > EncounterEvent . RefreshMGDB ( WinForms . Main . MGDatabasePath ) ) . Start ( ) ;
var main = new Main ( ) ;
splash . Invoke ( ( MethodInvoker ) ( ( ) = > splash . Close ( ) ) ) ;
Application . Run ( main ) ;
2014-06-28 21:22:05 +00:00
}
2016-08-22 01:05:41 +00:00
2019-10-17 03:52:09 +00:00
#if ! DEBUG
2017-11-24 20:03:57 +00:00
private static void Error ( string msg ) = > MessageBox . Show ( msg , "PKHeX Error" , MessageBoxButtons . OK , MessageBoxIcon . Stop ) ;
2017-02-03 03:14:48 +00:00
2016-08-22 01:05:41 +00:00
// 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
{
2017-11-24 20:03:57 +00:00
result = ErrorWindow . ShowErrorDialog ( "An unhandled exception has occurred.\nYou can continue running PKHeX, but please report this error." , t . Exception , true ) ;
2016-08-22 01:05:41 +00:00
}
2020-10-24 19:38:14 +00:00
#pragma warning disable CA1031 // Do not catch general exception types
2017-09-27 21:21:25 +00:00
catch ( Exception reportingException )
2020-10-24 19:38:14 +00:00
#pragma warning restore CA1031 // Do not catch general exception types
2016-08-22 01:05:41 +00:00
{
2017-11-24 20:03:57 +00:00
HandleReportingException ( t . Exception , reportingException ) ;
2016-08-22 01:05:41 +00:00
}
// 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.
2018-05-12 19:28:48 +00:00
// NOTE: This exception cannot be kept from terminating the application - it can only
// log the event, and inform the user about it.
2016-08-22 01:05:41 +00:00
private static void CurrentDomain_UnhandledException ( object sender , UnhandledExceptionEventArgs e )
{
2017-09-27 21:21:25 +00:00
var ex = e . ExceptionObject as Exception ;
2016-08-22 01:05:41 +00:00
try
{
2020-01-26 16:55:13 +00:00
if ( IsOldPkhexCorePresent ( ex ) )
{
Error ( "You have upgraded PKHeX incorrectly. Please delete PKHeX.Core.dll." ) ;
}
else if ( ex ! = null )
2017-09-27 21:21:25 +00:00
{
ErrorWindow . ShowErrorDialog ( "An unhandled exception has occurred.\nPKHeX must now close." , ex , false ) ;
}
else
{
2017-11-24 20:03:57 +00:00
Error ( "A fatal non-UI error has occurred in PKHeX, and the details could not be displayed. Please report this to the author." ) ;
2017-09-27 21:21:25 +00:00
}
2016-08-22 01:05:41 +00:00
}
2020-10-24 19:38:14 +00:00
#pragma warning disable CA1031 // Do not catch general exception types
2017-09-27 21:21:25 +00:00
catch ( Exception reportingException )
2020-10-24 19:38:14 +00:00
#pragma warning restore CA1031 // Do not catch general exception types
2016-08-22 01:05:41 +00:00
{
2017-11-24 20:03:57 +00:00
HandleReportingException ( ex , reportingException ) ;
}
}
2020-10-24 18:59:35 +00:00
private static void HandleReportingException ( Exception ? ex , Exception reportingException )
2017-11-24 20:03:57 +00:00
{
2020-10-24 19:38:14 +00:00
if ( reportingException is FileNotFoundException x & & x . FileName ? . StartsWith ( "PKHeX.Core" ) = = true )
2017-11-24 20:03:57 +00:00
{
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 ( ) ;
2016-08-22 01:05:41 +00:00
}
}
2017-09-27 21:21:25 +00:00
/// <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>
2020-10-24 18:59:35 +00:00
private static bool EmergencyErrorLog ( Exception ? originalException , Exception errorHandlingException )
2017-09-27 21:21:25 +00:00
{
try
{
// Not using a string builder because something's very wrong, and we don't want to make things worse
2017-09-30 05:58:25 +00:00
var message = ( originalException ? . ToString ( ) ? ? "null first exception" ) + Environment . NewLine + errorHandlingException ;
2017-10-19 01:11:20 +00:00
File . WriteAllText ( $"PKHeX_Error_Report {DateTime.Now:yyyyMMddHHmmss}.txt" , message ) ;
2017-09-27 21:21:25 +00:00
}
2020-10-24 19:38:14 +00:00
#pragma warning disable CA1031 // Do not catch general exception types
2017-09-27 21:21:25 +00:00
catch ( Exception )
2020-10-24 19:38:14 +00:00
#pragma warning restore CA1031 // Do not catch general exception types
2017-09-27 21:21:25 +00:00
{
// We've failed to save the error details twice now. There's nothing else we can do.
return false ;
}
return true ;
}
2020-01-26 16:55:13 +00:00
2020-10-24 18:59:35 +00:00
private static bool IsOldPkhexCorePresent ( Exception ? ex )
2020-01-26 16:55:13 +00:00
{
return ex is MissingMethodException
& & File . Exists ( "PKHeX.Core.dll" )
& & AssemblyName . GetAssemblyName ( "PKHeX.Core.dll" ) . Version < Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version ;
}
2017-11-24 20:03:57 +00:00
#endif
2014-06-28 21:22:05 +00:00
}
}