Merge branch 'more-launch-checks' into 'master'
UI: Included more launch checks See merge request [ryubing/ryujinx!247](https://git.ryujinx.app/ryubing/ryujinx/-/merge_requests/247)
This commit is contained in:
commit
1208ab613e
@ -53,17 +53,39 @@ namespace Ryujinx.Ava
|
|||||||
{
|
{
|
||||||
if (!OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))
|
if (!OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))
|
||||||
{
|
{
|
||||||
_ = Win32NativeInterop.MessageBoxA(nint.Zero, "You are running an outdated version of Windows.\n\nRyujinx supports Windows 10 version 20H1 and newer.\n", $"Ryujinx {Version}", MbIconwarning);
|
Logger.Error?.PrintMsg(LogClass.Application, "Ryujinx is not intended to be run on an outdated version of Windows. Exiting...");
|
||||||
|
_ = Win32NativeInterop.MessageBoxA(nint.Zero,
|
||||||
|
"You are running an outdated version of Windows.\n\nRyujinx supports Windows 10 version 20H1 and newer.\n",
|
||||||
|
$"Ryujinx {Version}", MbIconwarning);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
|
string onedriveFiles = Environment.GetEnvironmentVariable("Onedrive");
|
||||||
var programFilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
|
string onedriveConsumerFiles = Environment.GetEnvironmentVariable("OnedriveConsumer");
|
||||||
|
string onedriveCommercialFiles = Environment.GetEnvironmentVariable("OnedriveCommercial");
|
||||||
|
|
||||||
|
// Apparently not everyone has OneDrive shoved onto their system.
|
||||||
|
if ((onedriveFiles is not null && Environment.CurrentDirectory.StartsWithIgnoreCase(onedriveFiles))
|
||||||
|
|| (onedriveConsumerFiles is not null && Environment.CurrentDirectory.StartsWithIgnoreCase(onedriveConsumerFiles))
|
||||||
|
|| (onedriveCommercialFiles is not null && Environment.CurrentDirectory.StartsWithIgnoreCase(onedriveCommercialFiles)))
|
||||||
|
{
|
||||||
|
Logger.Error?.PrintMsg(LogClass.Application, "Ryujinx is not intended to be run from a OneDrive folder. Exiting...");
|
||||||
|
_ = Win32NativeInterop.MessageBoxA(nint.Zero,
|
||||||
|
"Ryujinx is not intended to be run from a OneDrive folder. Please move it out and relaunch.",
|
||||||
|
$"Ryujinx {Version}", MbIconwarning);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
|
||||||
|
string programFilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
|
||||||
|
|
||||||
if (Environment.CurrentDirectory.StartsWithIgnoreCase(programFiles) ||
|
if (Environment.CurrentDirectory.StartsWithIgnoreCase(programFiles) ||
|
||||||
Environment.CurrentDirectory.StartsWithIgnoreCase(programFilesX86))
|
Environment.CurrentDirectory.StartsWithIgnoreCase(programFilesX86))
|
||||||
{
|
{
|
||||||
_ = Win32NativeInterop.MessageBoxA(nint.Zero, "Ryujinx is not intended to be run from the Program Files folder. Please move it out and relaunch.", $"Ryujinx {Version}", MbIconwarning);
|
Logger.Error?.PrintMsg(LogClass.Application, "Ryujinx is not intended to be run from the Program Files folder. Exiting...");
|
||||||
|
_ = Win32NativeInterop.MessageBoxA(nint.Zero,
|
||||||
|
"Ryujinx is not intended to be run from the Program Files folder. Please move it out and relaunch.",
|
||||||
|
$"Ryujinx {Version}", MbIconwarning);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,10 +95,54 @@ namespace Ryujinx.Ava
|
|||||||
// ...but this reads like it checks if the current is in/has the Windows admin role? lol
|
// ...but this reads like it checks if the current is in/has the Windows admin role? lol
|
||||||
if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
|
if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
|
||||||
{
|
{
|
||||||
_ = Win32NativeInterop.MessageBoxA(nint.Zero, "Ryujinx is not intended to be run as administrator.", $"Ryujinx {Version}", MbIconwarning);
|
Logger.Error?.PrintMsg(LogClass.Application, "Ryujinx is not intended to be run as administrator. Exiting...");
|
||||||
|
_ = Win32NativeInterop.MessageBoxA(nint.Zero, "Ryujinx is not intended to be run as administrator.",
|
||||||
|
$"Ryujinx {Version}", MbIconwarning);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // Unix
|
||||||
|
{
|
||||||
|
// sudo check
|
||||||
|
[DllImport("libc")]
|
||||||
|
static extern uint geteuid();
|
||||||
|
bool root = geteuid().Equals(0);
|
||||||
|
|
||||||
|
if (OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
Logger.Error?.PrintMsg(LogClass.Application, "Ryujinx is not intended to be run as administrator. Exiting...");
|
||||||
|
macOSNativeInterop.SimpleMessageBox($"Ryujinx {Version}",
|
||||||
|
"Ryujinx is not intended to be run as administrator.", "Ok");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OperatingSystem.IsLinux())
|
||||||
|
{
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
Logger.Error?.PrintMsg(LogClass.Application, "Ryujinx is not intended to be run as administrator. Exiting...");
|
||||||
|
LinuxSDLInterop.SimpleMessageBox($"Ryujinx {Version}", "Ryujinx is not intended to be run as administrator.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
string container = Environment.GetEnvironmentVariable("container");
|
||||||
|
|
||||||
|
if (container is not null && container.EqualsIgnoreCase("flatpak"))
|
||||||
|
{
|
||||||
|
Logger.Warning?.PrintMsg(LogClass.Application, "This is very likely an unofficial build, Ryujinx does NOT have a flatpak!");
|
||||||
|
Logger.Info?.PrintMsg(LogClass.Application, "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
|
||||||
|
Logger.Info?.PrintMsg(LogClass.Application, "Please visit https://ryujinx.app/ for our official builds.");
|
||||||
|
Logger.Info?.PrintMsg(LogClass.Application,
|
||||||
|
" AppImage >> https://update.ryujinx.app/download/query?os=linuxappimage&arch=x64&rc=stable");
|
||||||
|
Logger.Info?.PrintMsg(LogClass.Application,
|
||||||
|
" Tarball >> https://update.ryujinx.app/download/query?os=linux&arch=x64&rc=stable");
|
||||||
|
Logger.Info?.PrintMsg(LogClass.Application, "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool noGuiArg = ConsumeCommandLineArgument(ref args, "--no-gui") || ConsumeCommandLineArgument(ref args, "nogui");
|
bool noGuiArg = ConsumeCommandLineArgument(ref args, "--no-gui") || ConsumeCommandLineArgument(ref args, "nogui");
|
||||||
bool coreDumpArg = ConsumeCommandLineArgument(ref args, "--core-dumps");
|
bool coreDumpArg = ConsumeCommandLineArgument(ref args, "--core-dumps");
|
||||||
@ -307,7 +373,7 @@ namespace Ryujinx.Ava
|
|||||||
"never" => HideCursorMode.Never,
|
"never" => HideCursorMode.Never,
|
||||||
"onidle" => HideCursorMode.OnIdle,
|
"onidle" => HideCursorMode.OnIdle,
|
||||||
"always" => HideCursorMode.Always,
|
"always" => HideCursorMode.Always,
|
||||||
_ => ConfigurationState.Instance.HideCursor,
|
_ => ConfigurationState.Instance.HideCursor
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if memoryManagerMode was overridden.
|
// Check if memoryManagerMode was overridden.
|
||||||
|
|||||||
30
src/Ryujinx/UI/Helpers/LinuxSDLInterop.cs
Normal file
30
src/Ryujinx/UI/Helpers/LinuxSDLInterop.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
{
|
||||||
|
public class LinuxSDLInterop
|
||||||
|
{
|
||||||
|
// TODO: add a parameter for prompt style
|
||||||
|
// TODO: look into adding text for the button
|
||||||
|
// TODO: check success of prompt box
|
||||||
|
public static int SimpleMessageBox(string caption, string text)
|
||||||
|
{
|
||||||
|
const string sdl = "SDL2";
|
||||||
|
|
||||||
|
[DllImport(sdl)]
|
||||||
|
static extern int SDL_Init(uint flags);
|
||||||
|
|
||||||
|
[DllImport(sdl, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern int SDL_ShowSimpleMessageBox(uint flags, string title, string message, IntPtr window);
|
||||||
|
|
||||||
|
[DllImport(sdl)]
|
||||||
|
static extern void SDL_Quit();
|
||||||
|
|
||||||
|
SDL_Init(0);
|
||||||
|
SDL_ShowSimpleMessageBox(32 /* 32 = warning style */, caption, text, IntPtr.Zero);
|
||||||
|
SDL_Quit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/Ryujinx/UI/Helpers/macOSNativeInterop.cs
Normal file
62
src/Ryujinx/UI/Helpers/macOSNativeInterop.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
{
|
||||||
|
public class macOSNativeInterop
|
||||||
|
{
|
||||||
|
// TODO: add a parameter for prompt style
|
||||||
|
// TODO: check success of prompt box
|
||||||
|
public static int SimpleMessageBox(string caption, string text, string button)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Grab what we need to make the message box.
|
||||||
|
const string ObjCRuntime = "/usr/lib/libobjc.A.dylib";
|
||||||
|
const string FoundationFramework = "/System/Library/Frameworks/Foundation.framework/Foundation";
|
||||||
|
const string AppKitFramework = "/System/Library/Frameworks/AppKit.framework/AppKit";
|
||||||
|
|
||||||
|
[DllImport(ObjCRuntime, EntryPoint = "sel_registerName")]
|
||||||
|
static extern IntPtr GetSelector(string name);
|
||||||
|
|
||||||
|
[DllImport(ObjCRuntime, EntryPoint = "objc_getClass")]
|
||||||
|
static extern IntPtr GetClass(string name);
|
||||||
|
|
||||||
|
[DllImport(FoundationFramework, EntryPoint = "objc_msgSend")]
|
||||||
|
static extern IntPtr SendMessage(IntPtr target, IntPtr selector);
|
||||||
|
|
||||||
|
[DllImport(FoundationFramework, EntryPoint = "objc_msgSend")]
|
||||||
|
static extern IntPtr SendMessageWithParameter(IntPtr target, IntPtr selector, IntPtr param);
|
||||||
|
|
||||||
|
[DllImport(ObjCRuntime)]
|
||||||
|
static extern IntPtr dlopen(string path, int mode);
|
||||||
|
|
||||||
|
dlopen(AppKitFramework, 0x1); // have to invoke AppKit so that NSAlert doesn't return a null pointer
|
||||||
|
|
||||||
|
IntPtr NSStringClass = GetClass("NSString");
|
||||||
|
IntPtr Selector = GetSelector("stringWithUTF8String:");
|
||||||
|
IntPtr SharedApp = SendMessage(GetClass("NSApplication"), GetSelector("sharedApplication"));
|
||||||
|
IntPtr NSAlert = SendMessage(GetClass("NSAlert"), GetSelector("alloc"));
|
||||||
|
IntPtr AlertInstance = SendMessage(NSAlert, GetSelector("init"));
|
||||||
|
|
||||||
|
// Create caption, text, and button text.
|
||||||
|
IntPtr boxCaption = SendMessageWithParameter(NSStringClass, Selector, Marshal.StringToHGlobalAnsi(caption));
|
||||||
|
IntPtr boxText = SendMessageWithParameter(NSStringClass, Selector, Marshal.StringToHGlobalAnsi(text));
|
||||||
|
IntPtr boxButton = SendMessageWithParameter(NSStringClass, Selector, Marshal.StringToHGlobalAnsi(button));
|
||||||
|
|
||||||
|
// Set up the window.
|
||||||
|
SendMessageWithParameter(SharedApp, GetSelector("setActivationPolicy:"), IntPtr.Zero); // Give it a window.
|
||||||
|
SendMessageWithParameter(SharedApp, GetSelector("activateIgnoringOtherApps:"), (IntPtr) 1); // Force it to the front.
|
||||||
|
|
||||||
|
// Set up the message box.
|
||||||
|
SendMessageWithParameter(AlertInstance, GetSelector("setAlertStyle:"), IntPtr.Zero); // Set style to warning.
|
||||||
|
SendMessageWithParameter(AlertInstance, GetSelector("setMessageText:"), boxCaption);
|
||||||
|
SendMessageWithParameter(AlertInstance, GetSelector("setInformativeText:"), boxText);
|
||||||
|
SendMessageWithParameter(AlertInstance, GetSelector("addButtonWithTitle:"), boxButton);
|
||||||
|
|
||||||
|
// Send prompt to user, then clean up.
|
||||||
|
SendMessage(AlertInstance, GetSelector("runModal"));
|
||||||
|
SendMessage(AlertInstance, GetSelector("release"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user