UI: Correctly set 'shell/open/command; registry key for file associations (#5244)

* Correctly set 'shell/open/command; registry key for file associations

* File association fixes
* 'using' statements instead of blocks
* Idempotent unregistration
* Single "hey shell, we changed file associations" notification at the
  end instead of 1 for every operation, speeds things up greatly.

* Adapt and fix Linux specific function as well

---------

Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
This commit is contained in:
mmdurrant 2023-06-12 18:36:40 -06:00 committed by GitHub
parent cf4c78b9c8
commit 5bd2c58ad6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -11,10 +11,10 @@ namespace Ryujinx.Ui.Common.Helper
{ {
public static partial class FileAssociationHelper public static partial class FileAssociationHelper
{ {
private static string[] _fileExtensions = new string[] { ".nca", ".nro", ".nso", ".nsp", ".xci" }; private static readonly string[] _fileExtensions = { ".nca", ".nro", ".nso", ".nsp", ".xci" };
[SupportedOSPlatform("linux")] [SupportedOSPlatform("linux")]
private static string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime"); private static readonly string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
private const int SHCNE_ASSOCCHANGED = 0x8000000; private const int SHCNE_ASSOCCHANGED = 0x8000000;
private const int SHCNF_FLUSH = 0x1000; private const int SHCNF_FLUSH = 0x1000;
@ -32,7 +32,7 @@ namespace Ryujinx.Ui.Common.Helper
{ {
string installKeyword = uninstall ? "uninstall" : "install"; string installKeyword = uninstall ? "uninstall" : "install";
if (!AreMimeTypesRegisteredLinux()) if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux()))
{ {
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml"); string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
string additionalArgs = !uninstall ? "--novendor" : ""; string additionalArgs = !uninstall ? "--novendor" : "";
@ -81,9 +81,9 @@ namespace Ryujinx.Ui.Common.Helper
return false; return false;
} }
key.OpenSubKey(@"shell\open\command"); var openCmd = key.OpenSubKey(@"shell\open\command");
string keyValue = (string)key.GetValue(""); string keyValue = (string)openCmd.GetValue("");
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName)); return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
} }
@ -107,30 +107,31 @@ namespace Ryujinx.Ui.Common.Helper
if (uninstall) if (uninstall)
{ {
// If the types don't already exist, there's nothing to do and we can call this operation successful.
if (!AreMimeTypesRegisteredWindows()) if (!AreMimeTypesRegisteredWindows())
{ {
return false; return true;
} }
Logger.Debug?.Print(LogClass.Application, $"Removing type association {ext}");
Registry.CurrentUser.DeleteSubKeyTree(keyString); Registry.CurrentUser.DeleteSubKeyTree(keyString);
Logger.Debug?.Print(LogClass.Application, $"Removed type association {ext}");
} }
else else
{ {
RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString); using var key = Registry.CurrentUser.CreateSubKey(keyString);
if (key is null) if (key is null)
{ {
return false; return false;
} }
key.CreateSubKey(@"shell\open\command"); Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
using var openCmd = key.CreateSubKey(@"shell\open\command");
openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
key.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
key.Close();
} }
// Notify Explorer the file association has been changed.
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
return true; return true;
} }
@ -141,6 +142,9 @@ namespace Ryujinx.Ui.Common.Helper
registered |= RegisterExtension(ext, uninstall); registered |= RegisterExtension(ext, uninstall);
} }
// Notify Explorer the file association has been changed.
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
return registered; return registered;
} }