Make config filename changable for releases & Log to Ryujinx directory if application directory is not writable (#4707)

* Remove GetBaseApplicationDirectory() & Move logs directory to user base path

We should assume the application directory might be write-protected.

* Use Ryujinx.sh in Ryujinx.desktop

This desktop file isn't really used right now,
so this changes effectively nothing.

* Use properties in ReleaseInformation.cs and add ConfigName property

* Configure config filename in Github workflows

* Add a separate config step for macOS

Because they use BSD sed instead of GNU sed

* Keep log directory at the old location for dev environments

* Add FileSystemUtils since Directory.Move() doesn't work across filesystems

Steal CopyDirectory code from https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories

* Fix "Open Logs folder" button pointing to the wrong directory

* Add execute permissions to Ryujinx.sh

* Fix missing newlines

* AppDataManager: Use FileSystemUtils.MoveDirectory()

* Make dotnet format happy

* Add a fallback for the logging directory
This commit is contained in:
TSRBerry 2024-01-29 19:58:18 +01:00 committed by GitHub
parent 7795b662a9
commit 70fcba39de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 209 additions and 117 deletions

View file

@ -49,6 +49,16 @@ jobs:
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Change config filename
run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
- name: Change config filename for macOS
run: sed -r -i '' 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
if: github.event_name == 'pull_request' && matrix.os == 'macOS-latest'
- name: Build
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
@ -135,6 +145,11 @@ jobs:
id: git_short_hash
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
- name: Change config filename
run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
if: github.event_name == 'pull_request'
- name: Publish macOS Ryujinx.Ava
run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"

View file

@ -85,6 +85,7 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Create output dir
@ -186,6 +187,7 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Publish macOS Ryujinx.Ava

View file

@ -4,7 +4,7 @@ Name=Ryujinx
Type=Application
Icon=Ryujinx
Exec=Ryujinx.sh %f
Comment=Plays Nintendo Switch applications
Comment=A Nintendo Switch Emulator
GenericName=Nintendo Switch Emulator
Terminal=false
Categories=Game;Emulator;

0
distribution/linux/Ryujinx.sh Normal file → Executable file
View file

View file

@ -665,7 +665,7 @@ namespace Ryujinx.Modules
return false;
}
if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid())
if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid)
{
if (showWarnings)
{
@ -683,7 +683,7 @@ namespace Ryujinx.Modules
#else
if (showWarnings)
{
if (ReleaseInformation.IsFlatHubBuild())
if (ReleaseInformation.IsFlatHubBuild)
{
Dispatcher.UIThread.InvokeAsync(() =>
ContentDialogHelper.CreateWarningDialog(

View file

@ -35,7 +35,7 @@ namespace Ryujinx.Ava
public static void Main(string[] args)
{
Version = ReleaseInformation.GetVersion();
Version = ReleaseInformation.Version;
if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134))
{
@ -125,8 +125,8 @@ namespace Ryujinx.Ava
public static void ReloadConfig()
{
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, "Config.json");
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
// Now load the configuration as the other subsystems are now registered
if (File.Exists(localConfigurationPath))

View file

@ -357,7 +357,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool OpenBcatSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
public bool CreateShortcutEnabled => !ReleaseInformation.IsFlatHubBuild();
public bool CreateShortcutEnabled => !ReleaseInformation.IsFlatHubBuild;
public string LoadHeading
{
@ -1350,7 +1350,12 @@ namespace Ryujinx.Ava.UI.ViewModels
public void OpenLogsFolder()
{
string logPath = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "Logs");
string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
if (ReleaseInformation.IsValid)
{
logPath = Path.Combine(AppDataManager.BaseDirPath, "Logs");
}
new DirectoryInfo(logPath).Create();

View file

@ -1,4 +1,5 @@
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using System;
using System.IO;
@ -6,8 +7,8 @@ namespace Ryujinx.Common.Configuration
{
public static class AppDataManager
{
public const string DefaultBaseDir = "Ryujinx";
public const string DefaultPortableDir = "portable";
private const string DefaultBaseDir = "Ryujinx";
private const string DefaultPortableDir = "portable";
// The following 3 are always part of Base Directory
private const string GamesDir = "games";
@ -109,8 +110,7 @@ namespace Ryujinx.Common.Configuration
string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir);
if (Path.Exists(oldConfigPath) && !IsPathSymlink(oldConfigPath) && !Path.Exists(BaseDirPath))
{
CopyDirectory(oldConfigPath, BaseDirPath);
Directory.Delete(oldConfigPath, true);
FileSystemUtils.MoveDirectory(oldConfigPath, BaseDirPath);
Directory.CreateSymbolicLink(oldConfigPath, BaseDirPath);
}
}
@ -127,41 +127,13 @@ namespace Ryujinx.Common.Configuration
}
// Check if existing old baseDirPath is a symlink, to prevent possible errors.
// Should be removed, when the existance of the old directory isn't checked anymore.
// Should be removed, when the existence of the old directory isn't checked anymore.
private static bool IsPathSymlink(string path)
{
FileAttributes attributes = File.GetAttributes(path);
return (attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint;
}
private static void CopyDirectory(string sourceDir, string destinationDir)
{
var dir = new DirectoryInfo(sourceDir);
if (!dir.Exists)
{
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
}
DirectoryInfo[] subDirs = dir.GetDirectories();
Directory.CreateDirectory(destinationDir);
foreach (FileInfo file in dir.GetFiles())
{
if (file.Name == ".DS_Store")
{
continue;
}
file.CopyTo(Path.Combine(destinationDir, file.Name));
}
foreach (DirectoryInfo subDir in subDirs)
{
CopyDirectory(subDir.FullName, Path.Combine(destinationDir, subDir.Name));
}
}
public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName;
public static string GetSdModsPath() => CustomSdModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultSdcardDir, "atmosphere")).FullName;
}

View file

@ -13,31 +13,71 @@ namespace Ryujinx.Common.Logging.Targets
string ILogTarget.Name { get => _name; }
public FileLogTarget(string path, string name)
: this(path, name, FileShare.Read, FileMode.Append)
{ }
public FileLogTarget(string name, FileStream fileStream)
{
_name = name;
_logWriter = new StreamWriter(fileStream);
_formatter = new DefaultLogFormatter();
}
public FileLogTarget(string path, string name, FileShare fileShare, FileMode fileMode)
public static FileStream PrepareLogFile(string path)
{
// Ensure directory is present
DirectoryInfo logDir = new(Path.Combine(path, "Logs"));
try
{
logDir.Create();
}
catch (IOException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}': {exception}");
return null;
}
// Clean up old logs, should only keep 3
FileInfo[] files = logDir.GetFiles("*.log").OrderBy((info => info.CreationTime)).ToArray();
for (int i = 0; i < files.Length - 2; i++)
{
try
{
files[i].Delete();
}
catch (UnauthorizedAccessException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Old log file could not be deleted '{files[i].FullName}': {exception}");
string version = ReleaseInformation.GetVersion();
return null;
}
catch (IOException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Old log file could not be deleted '{files[i].FullName}': {exception}");
return null;
}
}
string version = ReleaseInformation.Version;
// Get path for the current time
path = Path.Combine(logDir.FullName, $"Ryujinx_{version}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log");
_name = name;
_logWriter = new StreamWriter(File.Open(path, fileMode, FileAccess.Write, fileShare));
_formatter = new DefaultLogFormatter();
try
{
return File.Open(path, FileMode.Append, FileAccess.Write, FileShare.Read);
}
catch (UnauthorizedAccessException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Log file could not be created '{path}': {exception}");
return null;
}
catch (IOException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Log file could not be created '{path}': {exception}");
return null;
}
}
public void Log(object sender, LogEventArgs args)

View file

@ -1,5 +1,3 @@
using Ryujinx.Common.Configuration;
using System;
using System.Reflection;
namespace Ryujinx.Common
@ -9,50 +7,25 @@ namespace Ryujinx.Common
{
private const string FlatHubChannelOwner = "flathub";
public const string BuildVersion = "%%RYUJINX_BUILD_VERSION%%";
public const string BuildGitHash = "%%RYUJINX_BUILD_GIT_HASH%%";
public const string ReleaseChannelName = "%%RYUJINX_TARGET_RELEASE_CHANNEL_NAME%%";
private const string BuildVersion = "%%RYUJINX_BUILD_VERSION%%";
private const string BuildGitHash = "%%RYUJINX_BUILD_GIT_HASH%%";
private const string ReleaseChannelName = "%%RYUJINX_TARGET_RELEASE_CHANNEL_NAME%%";
private const string ConfigFileName = "%%RYUJINX_CONFIG_FILE_NAME%%";
public const string ReleaseChannelOwner = "%%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER%%";
public const string ReleaseChannelRepo = "%%RYUJINX_TARGET_RELEASE_CHANNEL_REPO%%";
public static bool IsValid()
{
return !BuildGitHash.StartsWith("%%") &&
public static string ConfigName => !ConfigFileName.StartsWith("%%") ? ConfigFileName : "Config.json";
public static bool IsValid =>
!BuildGitHash.StartsWith("%%") &&
!ReleaseChannelName.StartsWith("%%") &&
!ReleaseChannelOwner.StartsWith("%%") &&
!ReleaseChannelRepo.StartsWith("%%");
}
!ReleaseChannelRepo.StartsWith("%%") &&
!ConfigFileName.StartsWith("%%");
public static bool IsFlatHubBuild()
{
return IsValid() && ReleaseChannelOwner.Equals(FlatHubChannelOwner);
}
public static bool IsFlatHubBuild => IsValid && ReleaseChannelOwner.Equals(FlatHubChannelOwner);
public static string GetVersion()
{
if (IsValid())
{
return BuildVersion;
}
return Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
}
#if FORCE_EXTERNAL_BASE_DIR
public static string GetBaseApplicationDirectory()
{
return AppDataManager.BaseDirPath;
}
#else
public static string GetBaseApplicationDirectory()
{
if (IsFlatHubBuild() || OperatingSystem.IsMacOS())
{
return AppDataManager.BaseDirPath;
}
return AppDomain.CurrentDomain.BaseDirectory;
}
#endif
public static string Version => IsValid ? BuildVersion : Assembly.GetEntryAssembly()!.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
}
}

View file

@ -0,0 +1,48 @@
using System.IO;
namespace Ryujinx.Common.Utilities
{
public static class FileSystemUtils
{
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
{
// Get information about the source directory
var dir = new DirectoryInfo(sourceDir);
// Check if the source directory exists
if (!dir.Exists)
{
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
}
// Cache directories before we start copying
DirectoryInfo[] dirs = dir.GetDirectories();
// Create the destination directory
Directory.CreateDirectory(destinationDir);
// Get the files in the source directory and copy to the destination directory
foreach (FileInfo file in dir.GetFiles())
{
string targetFilePath = Path.Combine(destinationDir, file.Name);
file.CopyTo(targetFilePath);
}
// If recursive and copying subdirectories, recursively call this method
if (recursive)
{
foreach (DirectoryInfo subDir in dirs)
{
string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
CopyDirectory(subDir.FullName, newDestinationDir, true);
}
}
}
public static void MoveDirectory(string sourceDir, string destinationDir)
{
CopyDirectory(sourceDir, destinationDir, true);
Directory.Delete(sourceDir, true);
}
}
}

View file

@ -61,7 +61,7 @@ namespace Ryujinx.Headless.SDL2
static void Main(string[] args)
{
Version = ReleaseInformation.GetVersion();
Version = ReleaseInformation.Version;
// Make process DPI aware for proper window sizing on high-res screens.
ForceDpiAware.Windows();
@ -426,13 +426,28 @@ namespace Ryujinx.Headless.SDL2
Logger.SetEnable(LogLevel.AccessLog, option.LoggingEnableFsAccessLog);
if (!option.DisableFileLog)
{
FileStream logFile = FileLogTarget.PrepareLogFile(AppDomain.CurrentDomain.BaseDirectory);
if (logFile == null)
{
logFile = FileLogTarget.PrepareLogFile(AppDataManager.BaseDirPath);
if (logFile == null)
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable.");
}
}
if (logFile != null)
{
Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget(ReleaseInformation.GetBaseApplicationDirectory(), "file"),
new FileLogTarget("file", logFile),
1000,
AsyncLogTargetOverflowAction.Block
));
}
}
// Setup graphics configuration
GraphicsConfig.EnableShaderCache = !option.DisableShaderCache;

View file

@ -1,4 +1,3 @@
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Concurrent;
@ -13,8 +12,6 @@ namespace Ryujinx.SDL2.Common
{
private static SDL2Driver _instance;
public static bool IsInitialized => _instance != null;
public static SDL2Driver Instance
{
get
@ -96,7 +93,7 @@ namespace Ryujinx.SDL2.Common
SDL_EventState(SDL_EventType.SDL_CONTROLLERSENSORUPDATE, SDL_DISABLE);
string gamepadDbPath = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "SDL_GameControllerDB.txt");
string gamepadDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SDL_GameControllerDB.txt");
if (File.Exists(gamepadDbPath))
{

View file

@ -8,6 +8,7 @@ using LibHac.Ns;
using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
@ -105,7 +106,7 @@ namespace Ryujinx.Ui.App.Common
if (!Directory.Exists(appDir))
{
Logger.Warning?.Print(LogClass.Application, $"The \"game_dirs\" section in \"Config.json\" contains an invalid directory: \"{appDir}\"");
Logger.Warning?.Print(LogClass.Application, $"The \"game_dirs\" section in \"{ReleaseInformation.ConfigName}\" contains an invalid directory: \"{appDir}\"");
continue;
}

View file

@ -1,7 +1,9 @@
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging.Targets;
using System;
using System.IO;
namespace Ryujinx.Ui.Common.Configuration
{
@ -80,8 +82,23 @@ namespace Ryujinx.Ui.Common.Configuration
{
if (e.NewValue)
{
FileStream logFile = FileLogTarget.PrepareLogFile(AppDomain.CurrentDomain.BaseDirectory);
if (logFile == null)
{
logFile = FileLogTarget.PrepareLogFile(AppDataManager.BaseDirPath);
if (logFile == null)
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable.");
Logger.RemoveTarget("file");
return;
}
}
Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget(ReleaseInformation.GetBaseApplicationDirectory(), "file"),
new FileLogTarget("file", logFile),
1000,
AsyncLogTargetOverflowAction.Block
));

View file

@ -22,7 +22,7 @@ namespace Ryujinx.Ui.Common.Helper
[LibraryImport("shell32.dll", SetLastError = true)]
public static partial void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild();
public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild;
[SupportedOSPlatform("linux")]
private static bool AreMimeTypesRegisteredLinux() => File.Exists(Path.Combine(_mimeDbPath, "packages", "Ryujinx.xml"));
@ -34,7 +34,7 @@ namespace Ryujinx.Ui.Common.Helper
if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux()))
{
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
string mimeTypesFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mime", "Ryujinx.xml");
string additionalArgs = !uninstall ? "--novendor" : "";
using Process mimeProcess = new();

View file

@ -1,6 +1,7 @@
using Gdk;
using Gtk;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Ui;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Common.Helper;
@ -52,7 +53,7 @@ namespace Ryujinx.Modules
ProcessStartInfo processStart = new(ryuName)
{
UseShellExecute = true,
WorkingDirectory = ReleaseInformation.GetBaseApplicationDirectory(),
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory
};
foreach (string argument in CommandLineState.Arguments)

View file

@ -532,7 +532,7 @@ namespace Ryujinx.Modules
return false;
}
if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid())
if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid)
{
if (showWarnings)
{
@ -546,7 +546,7 @@ namespace Ryujinx.Modules
#else
if (showWarnings)
{
if (ReleaseInformation.IsFlatHubBuild())
if (ReleaseInformation.IsFlatHubBuild)
{
GtkDialog.CreateWarningDialog("Updater Disabled!", "Please update Ryujinx via FlatHub.");
}

View file

@ -71,7 +71,7 @@ namespace Ryujinx
static void Main(string[] args)
{
Version = ReleaseInformation.GetVersion();
Version = ReleaseInformation.Version;
if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134))
{
@ -167,8 +167,8 @@ namespace Ryujinx
Quality = 100,
});
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, "Config.json");
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
// Now load the configuration as the other subsystems are now registered
ConfigurationPath = File.Exists(localConfigurationPath)

View file

@ -1,4 +1,5 @@
using Gtk;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Ui.Common.Configuration;
using System.IO;
@ -24,7 +25,7 @@ namespace Ryujinx.Ui.Helper
}
else
{
Logger.Warning?.Print(LogClass.Application, $"The \"custom_theme_path\" section in \"Config.json\" contains an invalid path: \"{ConfigurationState.Instance.Ui.CustomThemePath}\".");
Logger.Warning?.Print(LogClass.Application, $"The \"custom_theme_path\" section in \"{ReleaseInformation.ConfigName}\" contains an invalid path: \"{ConfigurationState.Instance.Ui.CustomThemePath}\".");
ConfigurationState.Instance.Ui.CustomThemePath.Value = "";
ConfigurationState.Instance.Ui.EnableCustomTheme.Value = false;

View file

@ -1376,7 +1376,12 @@ namespace Ryujinx.Ui
private void OpenLogsFolder_Pressed(object sender, EventArgs args)
{
string logPath = System.IO.Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "Logs");
string logPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
if (ReleaseInformation.IsValid)
{
logPath = System.IO.Path.Combine(AppDataManager.BaseDirPath, "Logs");
}
new DirectoryInfo(logPath).Create();

View file

@ -78,7 +78,7 @@ namespace Ryujinx.Ui.Widgets
_extractExeFsMenuItem.Sensitive = hasNca;
_extractLogoMenuItem.Sensitive = hasNca;
_createShortcutMenuItem.Sensitive = !ReleaseInformation.IsFlatHubBuild();
_createShortcutMenuItem.Sensitive = !ReleaseInformation.IsFlatHubBuild;
PopupAtPointer(null);
}