From 7c22506eb1468f6f991bbdd8c8af1002e859f478 Mon Sep 17 00:00:00 2001 From: Student Main Date: Sat, 18 Apr 2020 02:45:07 +0800 Subject: [PATCH] add protocol handler in registry --- .../Controller/System/ProtocolHandler.cs | 106 ++++++++++++++++++ shadowsocks-csharp/Program.cs | 9 +- shadowsocks-csharp/View/MenuViewController.cs | 13 +++ shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 shadowsocks-csharp/Controller/System/ProtocolHandler.cs diff --git a/shadowsocks-csharp/Controller/System/ProtocolHandler.cs b/shadowsocks-csharp/Controller/System/ProtocolHandler.cs new file mode 100644 index 00000000..f9dcc81e --- /dev/null +++ b/shadowsocks-csharp/Controller/System/ProtocolHandler.cs @@ -0,0 +1,106 @@ +using Microsoft.Win32; +using NLog; +using Shadowsocks.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Shadowsocks.Controller +{ + static class ProtocolHandler + { + private static Logger logger = LogManager.GetCurrentClassLogger(); + + // Don't use Application.ExecutablePath + // see https://stackoverflow.com/questions/12945805/odd-c-sharp-path-issue + private static readonly string ExecutablePath = Assembly.GetEntryAssembly().Location; + + // TODO: Elevate when necessary + public static bool Set(bool enabled) + { + RegistryKey runKey = null; + try + { + RegistryKey hkcr = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, + Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32); + + runKey = hkcr.CreateSubKey("ss",RegistryKeyPermissionCheck.ReadWriteSubTree); + if (runKey == null) + { + logger.Error(@"Cannot find HKCR\ss"); + return false; + } + if (enabled) + { + runKey.SetValue("", "URL:Shadowsocks"); + runKey.SetValue("URL Protocol", ""); + var shellOpen = runKey.CreateSubKey("shell").CreateSubKey("open").CreateSubKey("command"); + shellOpen.SetValue("", $"{ExecutablePath} --open-url %1"); + + } + else + { + hkcr.DeleteSubKeyTree("ss"); + } + return true; + } + catch (Exception e) + { + logger.LogUsefulException(e); + return false; + } + finally + { + if (runKey != null) + { + try + { + runKey.Close(); + runKey.Dispose(); + } + catch (Exception e) + { logger.LogUsefulException(e); } + } + } + } + + public static bool Check() + { + RegistryKey runKey = null; + try + { + runKey = Utils.OpenRegKey(@"ss", true, RegistryHive.ClassesRoot); + if (runKey == null) + { + logger.Error(@"Cannot find HKCR\ss"); + return false; + } + + var shellOpen = runKey.OpenSubKey("shell").OpenSubKey("open").OpenSubKey("command"); + return (string)shellOpen.GetValue("") == $"{ExecutablePath} --open-url %1"; + } + catch (Exception e) + { + logger.LogUsefulException(e); + return false; + } + finally + { + if (runKey != null) + { + try + { + runKey.Close(); + runKey.Dispose(); + } + catch (Exception e) + { logger.LogUsefulException(e); } + } + } + } + + } +} diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index cc4c1ea5..10c6d9fb 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -136,7 +136,14 @@ namespace Shadowsocks PipeServer pipeServer = new PipeServer(); Task.Run(() => pipeServer.Run(pipename)); - pipeServer.AddUrlRequested += (_1, e) => MainController.AddServerBySSURL(e.Url); + pipeServer.AddUrlRequested += (_1, e) => + { + var dr = MessageBox.Show($"Open url: {e.Url} ?", "Shadowsocks", MessageBoxButtons.YesNo); + if (dr == DialogResult.Yes) + { + MainController.AddServerBySSURL(e.Url); + } + }; Application.Run(); } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index ddcf21f4..72147693 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -36,6 +36,7 @@ namespace Shadowsocks.View private ContextMenu contextMenu1; private MenuItem disableItem; private MenuItem AutoStartupItem; + private MenuItem ProtocolHandlerItem; private MenuItem ShareOverLANItem; private MenuItem SeperatorItem; private MenuItem ConfigItem; @@ -315,6 +316,7 @@ namespace Shadowsocks.View this.proxyItem = CreateMenuItem("Forward Proxy...", new EventHandler(this.proxyItem_Click)), new MenuItem("-"), this.AutoStartupItem = CreateMenuItem("Start on Boot", new EventHandler(this.AutoStartupItem_Click)), + this.ProtocolHandlerItem = CreateMenuItem("Start on Boot", new EventHandler(this.ProtocolHandlerItem_Click)), this.ShareOverLANItem = CreateMenuItem("Allow other Devices to connect", new EventHandler(this.ShareOverLANItem_Click)), new MenuItem("-"), this.hotKeyItem = CreateMenuItem("Edit Hotkeys...", new EventHandler(this.hotKeyItem_Click)), @@ -442,6 +444,7 @@ namespace Shadowsocks.View VerboseLoggingToggleItem.Checked = config.isVerboseLogging; ShowPluginOutputToggleItem.Checked = config.showPluginOutput; AutoStartupItem.Checked = AutoStartup.Check(); + ProtocolHandlerItem.Checked = ProtocolHandler.Check(); onlinePACItem.Checked = onlinePACItem.Enabled && config.useOnlinePac; localPACItem.Checked = !onlinePACItem.Checked; secureLocalPacUrlToggleItem.Checked = config.secureLocalPac; @@ -845,6 +848,16 @@ namespace Shadowsocks.View { MessageBox.Show(I18N.GetString("Failed to update registry")); } + LoadCurrentConfiguration(); + } + private void ProtocolHandlerItem_Click(object sender, EventArgs e) + { + ProtocolHandlerItem.Checked = !ProtocolHandlerItem.Checked; + if (!ProtocolHandler.Set(ProtocolHandlerItem.Checked)) + { + MessageBox.Show(I18N.GetString("Failed to update registry")); + } + LoadCurrentConfiguration(); } private void LocalPACItem_Click(object sender, EventArgs e) diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 83dd3ecf..553573dc 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -114,6 +114,7 @@ +