From 5bd2c58ad63ba42cb22d1525585efeacaef10c46 Mon Sep 17 00:00:00 2001
From: mmdurrant <mmdurrant@users.noreply.github.com>
Date: Mon, 12 Jun 2023 18:36:40 -0600
Subject: 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>
---
 .../Helper/FileAssociationHelper.cs                | 32 ++++++++++++----------
 1 file changed, 18 insertions(+), 14 deletions(-)

(limited to 'src')

diff --git a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
index 4f4b2524..542db9a7 100644
--- a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
+++ b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
@@ -11,10 +11,10 @@ namespace Ryujinx.Ui.Common.Helper
 {
     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")]
-        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 SHCNF_FLUSH        = 0x1000;
@@ -32,7 +32,7 @@ namespace Ryujinx.Ui.Common.Helper
         {
             string installKeyword = uninstall ? "uninstall" : "install";
 
-            if (!AreMimeTypesRegisteredLinux())
+            if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux()))
             {
                 string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
                 string additionalArgs = !uninstall ? "--novendor" : "";
@@ -81,9 +81,9 @@ namespace Ryujinx.Ui.Common.Helper
                     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));
             }
@@ -107,30 +107,31 @@ namespace Ryujinx.Ui.Common.Helper
 
                 if (uninstall)
                 {
+                    // If the types don't already exist, there's nothing to do and we can call this operation successful.
                     if (!AreMimeTypesRegisteredWindows())
                     {
-                        return false;
+                        return true;
                     }
-
+                    Logger.Debug?.Print(LogClass.Application, $"Removing type association {ext}");
                     Registry.CurrentUser.DeleteSubKeyTree(keyString);
+                    Logger.Debug?.Print(LogClass.Application, $"Removed type association {ext}");
                 }
                 else
                 {
-                    RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString);
+                    using var key = Registry.CurrentUser.CreateSubKey(keyString);
+
                     if (key is null)
                     {
                         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;
             }
 
@@ -141,6 +142,9 @@ namespace Ryujinx.Ui.Common.Helper
                 registered |= RegisterExtension(ext, uninstall);
             }
 
+            // Notify Explorer the file association has been changed.
+            SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
+
             return registered;
         }
 
-- 
cgit v1.2.3-70-g09d2