2017-02-03 03:14:48 +00:00
using Microsoft.Win32 ;
using System ;
using System.Diagnostics ;
2017-11-24 20:03:57 +00:00
using System.Windows.Forms ;
#if ! DEBUG
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
2017-11-24 20:03:57 +00:00
if ( ! CheckNETFramework ( ) )
return ;
2016-08-22 01:05:41 +00:00
// Run the application
2014-06-28 21:22:05 +00:00
Application . EnableVisualStyles ( ) ;
Application . SetCompatibleTextRenderingDefault ( false ) ;
2015-09-21 03:34:09 +00:00
Application . Run ( new Main ( ) ) ;
2014-06-28 21:22:05 +00:00
}
2016-08-22 01:05:41 +00:00
2017-11-24 20:03:57 +00:00
private static bool CheckNETFramework ( )
{
if ( IsOnWindows ( ) )
{
2018-05-12 19:28:48 +00:00
#if MONO
2017-11-24 20:03:57 +00:00
Error ( "Mono version should not be used on a Windows system." ) ;
#endif
if ( GetFrameworkVersion ( ) > = 393295 )
return true ;
Error ( ".NET Framework 4.6 needs to be installed for this version of PKHeX to run." ) ;
2018-05-12 19:28:48 +00:00
Process . Start ( "https://www.microsoft.com/download/details.aspx?id=48130" ) ;
2017-11-24 20:03:57 +00:00
return false ;
}
//CLR Version 4.0.30319.42000 is equivalent to .NET Framework version 4.6
if ( Environment . Version . CompareTo ( Version . Parse ( "4.0.30319.42000" ) ) > = 0 )
return true ;
Error ( "Your version of Mono needs to target the .NET Framework 4.6 or higher for this version of PKHeX to run." ) ;
return false ;
}
2017-06-18 01:37:19 +00:00
private static bool IsOnWindows ( )
2017-02-13 18:55:02 +00:00
{
// 4 -> UNIX, 6 -> Mac OSX, 128 -> UNIX (old)
int p = ( int ) Environment . OSVersion . Platform ;
2017-06-18 01:37:19 +00:00
return p ! = 4 & & p ! = 6 & & p ! = 128 ;
2017-02-13 18:55:02 +00:00
}
2017-06-18 01:37:19 +00:00
private static int GetFrameworkVersion ( )
2017-02-03 03:14:48 +00:00
{
const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\" ;
using ( RegistryKey ndpKey = RegistryKey . OpenBaseKey ( RegistryHive . LocalMachine , RegistryView . Registry32 ) . OpenSubKey ( subkey ) )
{
2017-06-18 01:37:19 +00:00
if ( ndpKey = = null )
return 0 ;
2017-02-03 03:14:48 +00:00
int releaseKey = ( int ) ndpKey . GetValue ( "Release" ) ;
return releaseKey ;
}
}
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
2017-11-24 20:03:57 +00:00
#if ! DEBUG
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
}
2017-09-27 21:21:25 +00:00
catch ( Exception reportingException )
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
{
2017-09-27 21:21:25 +00:00
if ( ex ! = null )
{
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
}
2017-09-27 21:21:25 +00:00
catch ( Exception reportingException )
2016-08-22 01:05:41 +00:00
{
2017-11-24 20:03:57 +00:00
HandleReportingException ( ex , reportingException ) ;
}
}
private static void HandleReportingException ( Exception ex , Exception reportingException )
{
if ( reportingException is FileNotFoundException x & & x . FileName . StartsWith ( "PKHeX.Core" ) )
{
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>
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
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
}
catch ( Exception )
{
// We've failed to save the error details twice now. There's nothing else we can do.
return false ;
}
return true ;
}
2017-11-24 20:03:57 +00:00
#endif
2014-06-28 21:22:05 +00:00
}
}