@@ -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); } | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
@@ -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) | |||
@@ -114,6 +114,7 @@ | |||
<Compile Include="Controller\LoggerExtension.cs" /> | |||
<Compile Include="Controller\Service\PACDaemon.cs" /> | |||
<Compile Include="Controller\Service\PipeServer.cs" /> | |||
<Compile Include="Controller\System\ProtocolHandler.cs" /> | |||
<Compile Include="Controller\System\Hotkeys\HotkeyCallbacks.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADEncryptor.cs" /> | |||
<Compile Include="Encryption\AEAD\AEADMbedTLSEncryptor.cs" /> | |||