Add a separate sanity check for SMX.dll existing, since Windows gives the same error if a DLL is missing or one of its dependencies is missing.
This commit is contained in:
parent
8ea8070d51
commit
3d6eb112e6
@ -15,9 +15,16 @@ namespace smx_config
|
||||
{
|
||||
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionEventHandler;
|
||||
|
||||
if(!SMX.SMX.DLLExists())
|
||||
{
|
||||
MessageBox.Show("SMXConfig encountered an unexpected error.\n\nSMX.dll couldn't be found:\n\n" + Helpers.GetLastWin32ErrorString(), "SMXConfig");
|
||||
Current.Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!SMX.SMX.DLLAvailable())
|
||||
{
|
||||
MessageBox.Show("SMXConfig encountered an unexpected error:\n\nSMX.dll failed to load.", "SMXConfig");
|
||||
MessageBox.Show("SMXConfig encountered an unexpected error.\n\nSMX.dll failed to load:\n\n" + Helpers.GetLastWin32ErrorString(), "SMXConfig");
|
||||
Current.Shutdown();
|
||||
return;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using SMXJSON;
|
||||
@ -79,6 +80,15 @@ namespace smx_config
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the last Win32 error as a string.
|
||||
public static string GetLastWin32ErrorString()
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
if(error == 0)
|
||||
return "";
|
||||
return new System.ComponentModel.Win32Exception(error).Message;
|
||||
}
|
||||
|
||||
// Work around Enumerable.SequenceEqual not checking if the arrays are null.
|
||||
public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
|
||||
{
|
||||
|
@ -198,8 +198,27 @@ namespace SMX
|
||||
|
||||
public static class SMX
|
||||
{
|
||||
[System.Flags]
|
||||
enum LoadLibraryFlags : uint
|
||||
{
|
||||
None = 0,
|
||||
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
|
||||
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
|
||||
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
|
||||
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
|
||||
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
|
||||
LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200,
|
||||
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000,
|
||||
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100,
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800,
|
||||
LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400,
|
||||
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
|
||||
}
|
||||
|
||||
[DllImport("kernel32", SetLastError=true)]
|
||||
static extern IntPtr LoadLibrary(string lpFileName);
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
|
||||
[DllImport("SMX.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void SMX_Start(
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)] InternalUpdateCallback callback,
|
||||
@ -229,11 +248,21 @@ namespace SMX
|
||||
private static extern bool SMX_ReenableAutoLights();
|
||||
|
||||
// Check if the native DLL is available. This is mostly to avoid exceptions in the designer.
|
||||
// This returns false if the DLL doesn't load.
|
||||
public static bool DLLAvailable()
|
||||
{
|
||||
|
||||
return LoadLibrary("SMX.dll") != IntPtr.Zero;
|
||||
}
|
||||
|
||||
// Check if the native DLL exists. This will return false if SMX.dll is missing entirely,
|
||||
// but not if it fails to load for another reason like runtime dependencies. This just lets
|
||||
// us print a more specific error message.
|
||||
public static bool DLLExists()
|
||||
{
|
||||
return LoadLibraryEx("SMX.dll", (IntPtr)0, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE) != IntPtr.Zero;
|
||||
}
|
||||
|
||||
public delegate void UpdateCallback(int PadNumber, SMXUpdateCallbackReason reason);
|
||||
|
||||
// The C API allows a user pointer, but we don't use that here.
|
||||
|
Loading…
x
Reference in New Issue
Block a user