2011-01-11 02:55:51 +00:00
using System ;
2017-04-10 00:59:23 +00:00
using System.Diagnostics ;
2012-10-29 08:37:22 +00:00
using System.IO ;
2013-07-27 00:30:08 +00:00
using System.Collections.Generic ;
2012-10-29 08:37:22 +00:00
using System.Reflection ;
using System.Runtime.InteropServices ;
2011-01-11 02:55:51 +00:00
using System.Windows.Forms ;
2019-05-18 10:17:02 +00:00
2011-05-23 00:33:05 +00:00
using Microsoft.VisualBasic.ApplicationServices ;
2011-01-11 02:55:51 +00:00
2013-10-27 22:07:40 +00:00
using BizHawk.Common ;
2013-10-25 00:57:23 +00:00
using BizHawk.Client.Common ;
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
using OSTC = EXE_PROJECT . OSTailoredCode ;
2013-11-03 03:54:37 +00:00
namespace BizHawk.Client.EmuHawk
2011-01-11 02:55:51 +00:00
{
2019-05-18 05:14:08 +00:00
internal static class Program
2011-06-19 23:39:25 +00:00
{
2013-01-02 20:11:27 +00:00
static Program ( )
2011-06-19 23:39:25 +00:00
{
2016-05-05 14:01:01 +00:00
//this needs to be done before the warnings/errors show up
Application . EnableVisualStyles ( ) ;
Application . SetCompatibleTextRenderingDefault ( false ) ;
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
if ( OSTC . IsUnixHost )
2019-11-04 04:30:05 +00:00
{
// for Unix, skip everything else and just wire up the event handler
AppDomain . CurrentDomain . AssemblyResolve + = CurrentDomain_AssemblyResolve ;
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
return ;
2019-11-04 04:30:05 +00:00
}
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
static void CheckLib ( string dllToLoad , string desc )
2019-05-18 04:34:15 +00:00
{
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
var p = OSTC . LinkedLibManager . LoadOrNull ( dllToLoad ) ;
if ( p = = null )
2019-05-18 04:34:15 +00:00
{
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
using ( var box = new ExceptionBox ( $"EmuHawk needs {desc} in order to run! See the readme for more info. (EmuHawk will now close.)" ) ) box . ShowDialog ( ) ;
Process . GetCurrentProcess ( ) . Kill ( ) ;
return ;
2019-05-18 04:34:15 +00:00
}
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
OSTC . LinkedLibManager . FreeByPtr ( p . Value ) ;
}
CheckLib ( "vcruntime140.dll" , "Microsoft's Universal CRT (MSVC 14.0+ / VS 2015+)" ) ;
2020-01-20 22:29:10 +00:00
CheckLib ( "msvcr100.dll" , "Microsoft's Visual C++ Runtime 10.0 (VS 2010)" ) ; // for Mupen64Plus, and some others
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
// this will look in subdirectory "dll" to load pinvoked stuff
var dllDir = Path . Combine ( Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) , "dll" ) ;
SetDllDirectory ( dllDir ) ;
//in case assembly resolution fails, such as if we moved them into the dll subdiretory, this event handler can reroute to them
AppDomain . CurrentDomain . AssemblyResolve + = CurrentDomain_AssemblyResolve ;
//but before we even try doing that, whack the MOTW from everything in that directory (thats a dll)
//otherwise, some people will have crashes at boot-up due to .net security disliking MOTW.
//some people are getting MOTW through a combination of browser used to download bizhawk, and program used to dearchive it
//We need to do it here too... otherwise people get exceptions when externaltools we distribute try to startup
static void RemoveMOTW ( string path ) = > DeleteFileW ( $"{path}:Zone.Identifier" ) ;
var todo = new Queue < DirectoryInfo > ( new [ ] { new DirectoryInfo ( dllDir ) } ) ;
while ( todo . Count ! = 0 )
{
var di = todo . Dequeue ( ) ;
foreach ( var disub in di . GetDirectories ( ) ) todo . Enqueue ( disub ) ;
foreach ( var fi in di . GetFiles ( "*.dll" ) ) RemoveMOTW ( fi . FullName ) ;
foreach ( var fi in di . GetFiles ( "*.exe" ) ) RemoveMOTW ( fi . FullName ) ;
2018-11-04 17:05:20 +00:00
}
2013-01-02 20:11:27 +00:00
}
[STAThread]
2019-05-18 05:14:08 +00:00
private static int Main ( string [ ] args )
2013-01-02 20:11:27 +00:00
{
2019-05-18 10:25:33 +00:00
var exitCode = SubMain ( args ) ;
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
if ( OSTC . IsUnixHost )
2019-05-18 10:25:33 +00:00
{
Console . WriteLine ( "BizHawk has completed its shutdown routines, killing process..." ) ;
Process . GetCurrentProcess ( ) . Kill ( ) ;
}
return exitCode ;
2013-01-02 20:11:27 +00:00
}
//NoInlining should keep this code from getting jammed into Main() which would create dependencies on types which havent been setup by the resolver yet... or something like that
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
2019-05-18 05:14:08 +00:00
private static int SubMain ( string [ ] args )
2013-01-02 20:11:27 +00:00
{
2013-01-01 23:10:47 +00:00
// this check has to be done VERY early. i stepped through a debug build with wrong .dll versions purposely used,
// and there was a TypeLoadException before the first line of SubMain was reached (some static ColorType init?)
2012-12-25 20:36:04 +00:00
// zero 25-dec-2012 - only do for public builds. its annoying during development
2019-08-11 16:20:09 +00:00
// and don't bother when installed from a package manager i.e. not Windows --yoshi
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
if ( ! VersionInfo . DeveloperBuild & & ! OSTC . IsUnixHost )
2012-12-17 15:38:56 +00:00
{
var thisversion = typeof ( Program ) . Assembly . GetName ( ) . Version ;
2015-01-01 20:54:01 +00:00
var utilversion = Assembly . Load ( new AssemblyName ( "Bizhawk.Client.Common" ) ) . GetName ( ) . Version ;
var emulversion = Assembly . Load ( new AssemblyName ( "Bizhawk.Emulation.Cores" ) ) . GetName ( ) . Version ;
2012-12-17 15:38:56 +00:00
if ( thisversion ! = utilversion | | thisversion ! = emulversion )
{
MessageBox . Show ( "Conflicting revisions found! Don't mix .dll versions!" ) ;
2015-12-15 08:22:44 +00:00
return - 1 ;
2012-12-17 15:38:56 +00:00
}
}
2019-10-13 05:23:14 +00:00
TempFileManager . Start ( ) ;
2016-05-05 14:01:01 +00:00
2019-10-06 06:51:02 +00:00
HawkFile . ArchiveHandlerFactory = new SharpCompressArchiveHandler ( ) ;
2016-04-02 19:33:34 +00:00
2019-05-29 05:06:38 +00:00
string cmdConfigFile = ArgParser . GetCmdConfigFile ( args ) ;
if ( cmdConfigFile ! = null ) PathManager . SetDefaultIniPath ( cmdConfigFile ) ;
2018-03-22 19:55:29 +00:00
try
{
2018-12-23 05:23:57 +00:00
Global . Config = ConfigService . Load < Config > ( PathManager . DefaultIniPath ) ;
2019-11-01 18:53:37 +00:00
}
catch ( Exception e )
{
2018-03-22 19:55:29 +00:00
new ExceptionBox ( e ) . ShowDialog ( ) ;
2019-11-01 18:53:37 +00:00
new ExceptionBox ( "Since your config file is corrupted or from a different BizHawk version, we're going to recreate it. Back it up before proceeding if you want to investigate further." ) . ShowDialog ( ) ;
2018-12-23 05:23:57 +00:00
File . Delete ( PathManager . DefaultIniPath ) ;
Global . Config = ConfigService . Load < Config > ( PathManager . DefaultIniPath ) ;
2018-03-22 19:55:29 +00:00
}
2013-08-11 19:55:13 +00:00
Global . Config . ResolveDefaults ( ) ;
2018-03-22 19:55:29 +00:00
2019-10-13 05:23:14 +00:00
StringLogUtil . DefaultToDisk = Global . Config . MoviesOnDisk ;
2020-01-25 16:57:31 +00:00
StringLogUtil . DefaultToAWE = Global . Config . MoviesInAwe ;
2013-10-27 22:07:40 +00:00
2017-05-22 16:16:15 +00:00
// super hacky! this needs to be done first. still not worth the trouble to make this system fully proper
2019-05-18 05:14:08 +00:00
if ( Array . Exists ( args , arg = > arg . StartsWith ( "--gdi" , StringComparison . InvariantCultureIgnoreCase ) ) )
2014-12-16 19:35:52 +00:00
{
2020-01-21 14:05:56 +00:00
Global . Config . DispMethod = EDispMethod . GdiPlus ;
2014-12-16 19:35:52 +00:00
}
2017-05-22 16:16:15 +00:00
// create IGL context. we do this whether or not the user has selected OpenGL, so that we can run opengl-based emulator cores
2020-01-21 21:05:50 +00:00
GlobalWin . IGL_GL = new Bizware . BizwareGL . IGL_TK ( 2 , 0 , false ) ;
2014-12-08 02:15:42 +00:00
2017-05-22 16:16:15 +00:00
// setup the GL context manager, needed for coping with multiple opengl cores vs opengl display method
2019-12-21 18:03:16 +00:00
GLManager . CreateInstance ( ) ;
2015-03-06 03:05:46 +00:00
GlobalWin . GLManager = GLManager . Instance ;
2014-01-27 05:37:04 +00:00
2014-12-08 02:15:42 +00:00
//now create the "GL" context for the display method. we can reuse the IGL_TK context if opengl display method is chosen
2019-11-04 04:30:05 +00:00
REDO_DISPMETHOD :
2020-01-21 14:05:56 +00:00
if ( Global . Config . DispMethod = = EDispMethod . GdiPlus )
2019-12-21 18:03:16 +00:00
{
2020-01-21 21:05:50 +00:00
GlobalWin . GL = new Bizware . BizwareGL . IGL_GdiPlus ( ) ;
2019-12-21 18:03:16 +00:00
}
2020-01-21 14:05:56 +00:00
else if ( Global . Config . DispMethod = = EDispMethod . SlimDX9 )
2016-05-05 14:01:01 +00:00
{
try
{
2020-01-21 21:21:22 +00:00
GlobalWin . GL = new Bizware . BizwareGL . IGL_SlimDX9 ( ) ;
2016-05-05 14:01:01 +00:00
}
catch ( Exception ex )
{
2019-05-18 05:14:08 +00:00
new ExceptionBox ( new Exception ( "Initialization of Direct3d 9 Display Method failed; falling back to GDI+" , ex ) ) . ShowDialog ( ) ;
2017-05-22 16:16:15 +00:00
// fallback
2020-01-21 14:05:56 +00:00
Global . Config . DispMethod = EDispMethod . GdiPlus ;
2016-05-05 14:01:01 +00:00
goto REDO_DISPMETHOD ;
}
}
2014-12-08 02:15:42 +00:00
else
2014-12-16 20:24:14 +00:00
{
2014-12-08 02:15:42 +00:00
GlobalWin . GL = GlobalWin . IGL_GL ;
2017-05-22 16:16:15 +00:00
2019-12-21 18:03:16 +00:00
// check the opengl version and don't even try to boot this crap up if its too old
2019-05-18 05:14:08 +00:00
if ( GlobalWin . IGL_GL . Version < 200 )
2014-12-16 20:24:14 +00:00
{
2017-05-22 16:16:15 +00:00
// fallback
2020-01-21 14:05:56 +00:00
Global . Config . DispMethod = EDispMethod . GdiPlus ;
2014-12-16 20:24:14 +00:00
goto REDO_DISPMETHOD ;
}
}
2014-12-08 02:15:42 +00:00
2017-05-22 16:16:15 +00:00
// try creating a GUI Renderer. If that doesn't succeed. we fallback
2016-04-02 19:33:34 +00:00
try
{
2017-04-29 21:49:29 +00:00
using ( GlobalWin . GL . CreateRenderer ( ) ) { }
2016-04-02 19:33:34 +00:00
}
catch ( Exception ex )
{
2019-05-18 05:14:08 +00:00
new ExceptionBox ( new Exception ( "Initialization of Display Method failed; falling back to GDI+" , ex ) ) . ShowDialog ( ) ;
2016-04-02 19:33:34 +00:00
//fallback
2020-01-21 14:05:56 +00:00
Global . Config . DispMethod = EDispMethod . GdiPlus ;
2016-04-02 19:33:34 +00:00
goto REDO_DISPMETHOD ;
}
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
if ( ! OSTC . IsUnixHost )
2017-04-10 00:59:23 +00:00
{
2018-11-04 17:05:20 +00:00
//WHY do we have to do this? some intel graphics drivers (ig7icd64.dll 10.18.10.3304 on an unknown chip on win8.1) are calling SetDllDirectory() for the process, which ruins stuff.
//The relevant initialization happened just before in "create IGL context".
//It isn't clear whether we need the earlier SetDllDirectory(), but I think we do.
//note: this is pasted instead of being put in a static method due to this initialization code being sensitive to things like that, and not wanting to cause it to break
//pasting should be safe (not affecting the jit order of things)
2019-05-18 05:14:08 +00:00
var dllDir = Path . Combine ( Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) , "dll" ) ;
2018-11-04 17:05:20 +00:00
SetDllDirectory ( dllDir ) ;
2015-03-01 19:29:33 +00:00
}
2015-10-12 02:03:09 +00:00
2019-05-18 04:27:50 +00:00
try
{
if ( Global . Config . SingleInstanceMode )
{
try
{
2019-05-18 05:14:08 +00:00
new SingleInstanceController ( args ) . Run ( ) ;
2019-05-18 04:27:50 +00:00
}
catch ( ObjectDisposedException )
{
// Eat it, MainForm disposed itself and Run attempts to dispose of itself. Eventually we would want to figure out a way to prevent that, but in the meantime it is harmless, so just eat the error
}
}
else
{
2019-12-21 22:34:29 +00:00
using var mf = new MainForm ( args ) ;
var title = mf . Text ;
mf . Show ( ) ;
mf . Text = title ;
try
2019-05-18 04:27:50 +00:00
{
2019-12-21 22:34:29 +00:00
GlobalWin . ExitCode = mf . ProgramRunLoop ( ) ;
}
catch ( Exception e ) when ( Global . MovieSession . Movie . IsActive ( ) & & ! ( Debugger . IsAttached | | VersionInfo . DeveloperBuild ) )
{
var result = MessageBox . Show (
"EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)" ,
$"Fatal error: {e.GetType().Name}" ,
MessageBoxButtons . YesNo ,
MessageBoxIcon . Exclamation
) ;
if ( result = = DialogResult . Yes )
2019-05-18 04:27:50 +00:00
{
2019-12-21 22:34:29 +00:00
Global . MovieSession . Movie . Save ( ) ;
2019-05-18 04:27:50 +00:00
}
}
}
}
catch ( Exception e ) when ( ! Debugger . IsAttached )
{
new ExceptionBox ( e ) . ShowDialog ( ) ;
}
finally
{
GlobalWin . Sound ? . Dispose ( ) ;
GlobalWin . Sound = null ;
GlobalWin . GL . Dispose ( ) ;
Input . Cleanup ( ) ;
}
2018-11-04 17:05:20 +00:00
2015-10-12 02:03:09 +00:00
//cleanup:
//cleanup IGL stuff so we can get better refcounts when exiting process, for debugging
//DOESNT WORK FOR SOME REASON
//GlobalWin.IGL_GL = new Bizware.BizwareGL.Drivers.OpenTK.IGL_TK();
//GLManager.Instance.Dispose();
//if (GlobalWin.IGL_GL != GlobalWin.GL)
// GlobalWin.GL.Dispose();
//((IDisposable)GlobalWin.IGL_GL).Dispose();
2015-12-15 08:22:44 +00:00
//return 0 assuming things have gone well, non-zero values could be used as error codes or for scripting purposes
return GlobalWin . ExitCode ;
2015-10-12 02:03:09 +00:00
} //SubMain
2011-05-23 00:33:05 +00:00
2019-05-18 05:14:08 +00:00
//declared here instead of a more usual place to avoid dependencies on the more usual place
2012-10-29 08:37:22 +00:00
[DllImport("kernel32.dll", SetLastError = true)]
2019-05-18 05:14:08 +00:00
private static extern uint SetDllDirectory ( string lpPathName ) ;
2013-07-27 00:30:08 +00:00
2017-03-21 16:09:28 +00:00
[DllImport("kernel32.dll", EntryPoint = "DeleteFileW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
2019-05-18 05:14:08 +00:00
private static extern bool DeleteFileW ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string lpFileName ) ;
2017-03-21 16:09:28 +00:00
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
/// <remarks>http://www.codeproject.com/Articles/310675/AppDomain-AssemblyResolve-Event-Tips</remarks>
2019-05-18 05:14:08 +00:00
private static Assembly CurrentDomain_AssemblyResolve ( object sender , ResolveEventArgs args )
2012-10-29 08:37:22 +00:00
{
2019-05-18 05:14:08 +00:00
var requested = args . Name ;
2017-07-14 06:02:15 +00:00
//mutate filename depending on selection of lua core. here's how it works
//1. we build NLua to the output/dll/lua directory. that brings KopiLua with it
//2. We reference it from there, but we tell it not to copy local; that way there's no NLua in the output/dll directory
//3. When NLua assembly attempts to load, it can't find it
//I. if LuaInterface is selected by the user, we switch to requesting that.
// (those DLLs are built into the output/DLL directory)
2019-05-18 05:14:08 +00:00
//II. if NLua is selected by the user, we skip over this part;
2017-07-14 06:02:15 +00:00
// later, we look for NLua or KopiLua assembly names and redirect them to files located in the output/DLL/nlua directory
if ( new AssemblyName ( requested ) . Name = = "NLua" )
{
2017-07-14 18:45:57 +00:00
//this method referencing Global.Config makes assemblies get loaded, which isnt smart from the assembly resolver.
//so.. we're going to resort to something really bad.
//avert your eyes.
2019-05-18 05:14:08 +00:00
var configPath = Path . Combine ( Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) , "config.ini" ) ;
Simplify Windows prereqs (see desc.)
* Changed default sound/display methods to OpenAL/OpenGL on Windows to match
non-Windows, and replaced DirectInput with OpenTK input (needs regression
testing on Windows).
* (meta) As a result of the above, DirectX is no longer a prerequisite, leaving
only: .NET Framework 4.6.1 (comes with Win10, as does 4.8), MSVC 14 (also comes
with Win10), MSVC 12 for Mupen, and MSVC 10 for BSNES/Mupen.
* Refactored static Program ctor, using ExceptionBox for missing prereqs, and
removed PrereqsAlert.
* Added OS version check for Windows, with a flag in the config to skip it.
* Updated readme for Win7 EOL (and generally cleanup Windows sections).
2020-01-08 20:36:25 +00:00
if ( ! OSTC . IsUnixHost // LuaInterface is not currently working on Mono
2019-05-18 10:25:33 +00:00
& & File . Exists ( configPath )
2019-12-15 14:38:22 +00:00
& & ( Array . Find ( File . ReadAllLines ( configPath ) , line = > line . Contains ( " \"LuaEngine\": " ) ) ? ? string . Empty )
. Contains ( "0" ) )
2017-07-14 18:45:57 +00:00
{
2019-05-18 05:14:08 +00:00
requested = "LuaInterface" ;
2017-07-14 18:45:57 +00:00
}
2017-07-14 06:02:15 +00:00
}
2013-01-02 20:11:27 +00:00
lock ( AppDomain . CurrentDomain )
{
2019-05-18 05:14:08 +00:00
var firstAsm = Array . Find ( AppDomain . CurrentDomain . GetAssemblies ( ) , asm = > asm . FullName = = requested ) ;
if ( firstAsm ! = null ) return firstAsm ;
2013-01-02 20:11:27 +00:00
//load missing assemblies by trying to find them in the dll directory
2019-05-18 05:14:08 +00:00
var dllname = $"{new AssemblyName(requested).Name}.dll" ;
var directory = Path . Combine ( Path . GetDirectoryName ( Assembly . GetExecutingAssembly ( ) . Location ) , "dll" ) ;
var simpleName = new AssemblyName ( requested ) . Name ;
2017-07-14 06:02:15 +00:00
if ( simpleName = = "NLua" | | simpleName = = "KopiLua" ) directory = Path . Combine ( directory , "nlua" ) ;
2019-05-18 05:14:08 +00:00
var fname = Path . Combine ( directory , dllname ) ;
//it is important that we use LoadFile here and not load from a byte array; otherwise mixed (managed/unmanaged) assemblies can't load
return File . Exists ( fname ) ? Assembly . LoadFile ( fname ) : null ;
2013-01-02 20:11:27 +00:00
}
2012-10-29 08:37:22 +00:00
}
2019-05-18 05:14:08 +00:00
private class SingleInstanceController : WindowsFormsApplicationBase
2011-06-19 23:39:25 +00:00
{
2019-05-18 05:14:08 +00:00
private readonly string [ ] cmdArgs ;
2011-06-19 23:39:25 +00:00
public SingleInstanceController ( string [ ] args )
{
cmdArgs = args ;
IsSingleInstance = true ;
StartupNextInstance + = this_StartupNextInstance ;
}
2019-05-18 05:14:08 +00:00
public void Run ( ) = > Run ( cmdArgs ) ;
private void this_StartupNextInstance ( object sender , StartupNextInstanceEventArgs e )
2011-06-19 23:39:25 +00:00
{
2014-12-29 04:20:47 +00:00
if ( e . CommandLine . Count > = 1 )
2019-05-18 05:14:08 +00:00
( ( MainForm ) MainForm ) . LoadRom ( e . CommandLine [ 0 ] , new MainForm . LoadRomArgs { OpenAdvanced = new OpenAdvanced_OpenRom ( ) } ) ;
2011-06-19 23:39:25 +00:00
}
2011-05-23 00:33:05 +00:00
2011-06-19 23:39:25 +00:00
protected override void OnCreateMainForm ( )
{
2013-08-25 22:43:34 +00:00
MainForm = new MainForm ( cmdArgs ) ;
var title = MainForm . Text ;
MainForm . Show ( ) ;
MainForm . Text = title ;
2019-05-18 05:14:08 +00:00
GlobalWin . ExitCode = ( ( MainForm ) MainForm ) . ProgramRunLoop ( ) ;
2015-03-01 19:29:33 +00:00
}
2011-06-19 23:39:25 +00:00
}
}
2011-01-11 02:55:51 +00:00
}