Jelajahi Sumber

Support user and global settings and save to the registry!

Douglas Thrift 10 tahun lalu
induk
melakukan
099b985ad2
2 mengubah file dengan 58 tambahan dan 19 penghapusan
  1. 50 13
      ssh-handler/SettingsDialog.xaml.cs
  2. 8 6
      ssh-handler/SshHandler.cs

+ 50 - 13
ssh-handler/SettingsDialog.xaml.cs

@@ -24,29 +24,39 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
 using System.Reflection;
+using System.Security.Principal;
 using System.Windows;
 using System.Windows.Controls;
 using Microsoft.Win32;
 
 public partial class SettingsDialog : Window
 {
-    public SettingsDialog(IList<Handler> handlers)
+    private bool global = false;
+
+    public SettingsDialog(IList<Handler> handlers, string type)
     {
+        switch (type.ToLowerInvariant())
+        {
+        case "global":
+            global = true;
+
+            if (!new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
+                Elevate();
+            break;
+        }
+
         InitializeComponent();
 
-        IEnumerable<string> options = new string[0];
+        Title = "SSH Handler " + (global ? "Global" : "User") + " Settings";
 
-        using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Default), key = baseKey.OpenSubKey(@"ssh\shell\open\command"))
-            if (key != null)
-            {
-                string command = (string)key.GetValue(null);
-                if (!string.IsNullOrWhiteSpace(command))
-                {
-                    var args = Shell32.CommandLineToArgv(command);
+        IEnumerable<string> options;
 
-                    options = args.Skip(1).TakeWhile(arg => arg != "%1");
-                }
-            }
+        if (global)
+            using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default), key = baseKey.OpenSubKey(@"Software\Classes\ssh\shell\open\command"))
+                options = Options(key);
+        else
+            using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Default), key = baseKey.OpenSubKey(@"ssh\shell\open\command"))
+                options = Options(key);
 
         foreach (Handler handler in handlers)
             SettingsPanel.Children.Add(new HandlerSettingsBox(handler, options, ApplyButton));
@@ -71,6 +81,28 @@ public partial class SettingsDialog : Window
         ApplyButton.IsEnabled = true;
     }
 
+    private void Elevate()
+    {
+        ProcessStartInfo info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location, "/settings:" + (global ? "global" : "user"));
+
+        info.Verb = "runas";
+
+        Process.Start(info);
+        Environment.Exit(0);
+    }
+
+    private IEnumerable<string> Options(RegistryKey key)
+    {
+        if (key != null)
+        {
+            string command = (string)key.GetValue(null);
+            if (!string.IsNullOrWhiteSpace(command))
+                return Shell32.CommandLineToArgv(command).Skip(1).TakeWhile(arg => arg != "%1");
+        }
+
+        return new string[0];
+    }
+
     private bool Apply()
     {
         var args = new List<string>();
@@ -95,7 +127,12 @@ public partial class SettingsDialog : Window
 
         args.Add("\"%1\"");
 
-        Debug.WriteLine("{0}", string.Join(" ", args), null);
+        using (RegistryKey baseKey = RegistryKey.OpenBaseKey(global ? RegistryHive.LocalMachine : RegistryHive.CurrentUser, RegistryView.Default), key = baseKey.CreateSubKey(@"Software\Classes\ssh"), commandKey = key.CreateSubKey(@"shell\open\command"))
+        {
+            key.SetValue(null, "URL:SSH Protocol");
+            key.SetValue("URL Protocol", "");
+            commandKey.SetValue(null, string.Join(" ", args));
+        }
 
         return true;
     }

+ 8 - 6
ssh-handler/SshHandler.cs

@@ -43,7 +43,7 @@ public class SshHandler
         try
         {
             Regex usage = new Regex(@"^(?:/|--?)(?:h|help|usage|\?)$", RegexOptions.IgnoreCase);
-            Regex settings = new Regex(@"^(?:/|--?)settings$", RegexOptions.IgnoreCase);
+            Regex settings = new Regex(@"^(?:/|--?)settings(?:[:=](?<settings_type>.*))?$", RegexOptions.IgnoreCase);
             IList<string> uriParts = null;
 
             foreach (string arg in args)
@@ -52,8 +52,10 @@ public class SshHandler
                     if (usage.IsMatch(arg))
                         return Usage(0);
 
-                    if (settings.IsMatch(arg))
-                        return Settings();
+                    Match match;
+
+                    if ((match = settings.Match(arg)).Success)
+                        return Settings(match.Groups["settings_type"].Value);
 
                     if (!MatchHandler(arg))
                         uriParts = new List<string>(new string[] { arg });
@@ -90,16 +92,16 @@ public class SshHandler
         MessageBox.Show("ssh-handler [/settings] " +
             string.Join(" ", handlers.SelectMany(handler => handler.Options.Select(option => "[" + option + "]"))) +
             " <ssh-url>\n\n" +
-            "/settings -- Show settings dialog\n\n" +
+            "/settings[:(user|global)] -- Show settings dialog\n\n" +
             string.Join("\n\n", handlers.SelectMany(handler => handler.Options.Zip(handler.Usages, (option, usage) => option + " -- " + usage))),
             "SSH Handler Usage",
             MessageBoxButtons.OK, MessageBoxIcon.Information);
         return code;
     }
 
-    private static int Settings()
+    private static int Settings(string type)
     {
-        var settings = new SettingsDialog(handlers);
+        var settings = new SettingsDialog(handlers, type);
         var result = settings.ShowDialog();
         Debug.WriteLine("Settings result: {0}", result, null);