2017-02-03 03:14:48 +00:00
using Microsoft.Win32 ;
using System ;
using System.Diagnostics ;
2017-01-28 17:48:00 +00:00
using System.IO ;
2017-01-31 04:27:08 +00:00
using System.Reflection ;
2016-08-22 01:05:41 +00:00
using System.Threading ;
2014-06-28 21:22:05 +00:00
using System.Windows.Forms ;
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 ) ;
// 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
2017-01-28 17:48:00 +00:00
try
{
2017-02-13 18:55:02 +00:00
if ( IsOnWindows ( ) )
{
if ( GetFrameworkVersion ( ) > = 393295 )
{
StartPKHeX ( ) ;
}
else
{
// Todo: make this translatable
MessageBox . Show ( ".NET Framework 4.6 needs to be installed for this version of PKHeX to run." , "PKHeX Error" , MessageBoxButtons . OK , MessageBoxIcon . Stop ) ;
Process . Start ( @"https://www.microsoft.com/download/details.aspx?id=48130" ) ;
}
}
else
{
//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 )
{
StartPKHeX ( ) ;
}
else
{
MessageBox . Show ( "Your version of Mono needs to target the .NET Framework 4.6 or higher for this version of PKHeX to run." ,
"PKHeX Error" , MessageBoxButtons . OK , MessageBoxIcon . Stop ) ;
}
}
2017-02-13 12:06:54 +00:00
2017-01-28 17:48:00 +00:00
}
2017-01-31 04:27:08 +00:00
catch ( FileNotFoundException ex )
2017-01-28 17:48:00 +00:00
{
2017-01-31 04:27:08 +00:00
// Check whether or not the exception was from missing PKHeX.Core, rather than something else in the constructor of Main
if ( ex . TargetSite = = typeof ( Program ) . GetMethod ( nameof ( StartPKHeX ) , BindingFlags . Static | BindingFlags . NonPublic ) )
{
// Exception came from StartPKHeX and (probably) corresponds to missing PKHeX.Core
MessageBox . Show ( "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." , "PKHeX Error" , MessageBoxButtons . OK , MessageBoxIcon . Stop ) ;
return ;
}
2017-02-12 17:52:26 +00:00
// Exception came from Main
throw ;
2017-01-28 17:48:00 +00:00
}
}
2017-01-31 04:27:08 +00:00
private static void StartPKHeX ( )
2017-01-28 17:48:00 +00:00
{
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-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-02-13 12:06:54 +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 ;
}
}
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
{
2016-08-22 01:23:32 +00:00
// Todo: make this translatable
2017-01-08 23:27:00 +00:00
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
{
try
{
// Todo: make this translatable
2017-09-27 21:21:25 +00:00
MessageBox . Show ( "A fatal error has occurred in PKHeX, and there was a problem displaying the details. Please report this to the author." , "PKHeX Error" , MessageBoxButtons . OK , MessageBoxIcon . Stop ) ;
EmergencyErrorLog ( t . Exception , reportingException ) ;
2016-08-22 01:05:41 +00:00
}
finally
{
Application . Exit ( ) ;
}
}
// 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 )
{
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 )
{
// Todo: make this translatable
ErrorWindow . ShowErrorDialog ( "An unhandled exception has occurred.\nPKHeX must now close." , ex , false ) ;
}
else
{
MessageBox . Show ( "A fatal non-UI error has occurred in PKHeX, and the details could not be displayed. Please report this to the author." , "PKHeX Error" , MessageBoxButtons . OK , MessageBoxIcon . Stop ) ;
}
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
{
try
{
// Todo: make this translatable
2017-09-27 21:21:25 +00:00
MessageBox . Show ( "A fatal non-UI error has occurred in PKHeX, and there was a problem displaying the details. Please report this to the author." , "PKHeX Error" , MessageBoxButtons . OK , MessageBoxIcon . Stop ) ;
EmergencyErrorLog ( ex , reportingException ) ;
2016-08-22 01:05:41 +00:00
}
finally
{
Application . Exit ( ) ;
}
}
}
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 ;
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 ;
}
2014-06-28 21:22:05 +00:00
}
}