@@ -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(); | PipeServer pipeServer = new PipeServer(); | ||||
Task.Run(() => pipeServer.Run(pipename)); | 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(); | Application.Run(); | ||||
} | } | ||||
@@ -36,6 +36,7 @@ namespace Shadowsocks.View | |||||
private ContextMenu contextMenu1; | private ContextMenu contextMenu1; | ||||
private MenuItem disableItem; | private MenuItem disableItem; | ||||
private MenuItem AutoStartupItem; | private MenuItem AutoStartupItem; | ||||
private MenuItem ProtocolHandlerItem; | |||||
private MenuItem ShareOverLANItem; | private MenuItem ShareOverLANItem; | ||||
private MenuItem SeperatorItem; | private MenuItem SeperatorItem; | ||||
private MenuItem ConfigItem; | private MenuItem ConfigItem; | ||||
@@ -315,6 +316,7 @@ namespace Shadowsocks.View | |||||
this.proxyItem = CreateMenuItem("Forward Proxy...", new EventHandler(this.proxyItem_Click)), | this.proxyItem = CreateMenuItem("Forward Proxy...", new EventHandler(this.proxyItem_Click)), | ||||
new MenuItem("-"), | new MenuItem("-"), | ||||
this.AutoStartupItem = CreateMenuItem("Start on Boot", new EventHandler(this.AutoStartupItem_Click)), | 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)), | this.ShareOverLANItem = CreateMenuItem("Allow other Devices to connect", new EventHandler(this.ShareOverLANItem_Click)), | ||||
new MenuItem("-"), | new MenuItem("-"), | ||||
this.hotKeyItem = CreateMenuItem("Edit Hotkeys...", new EventHandler(this.hotKeyItem_Click)), | this.hotKeyItem = CreateMenuItem("Edit Hotkeys...", new EventHandler(this.hotKeyItem_Click)), | ||||
@@ -442,6 +444,7 @@ namespace Shadowsocks.View | |||||
VerboseLoggingToggleItem.Checked = config.isVerboseLogging; | VerboseLoggingToggleItem.Checked = config.isVerboseLogging; | ||||
ShowPluginOutputToggleItem.Checked = config.showPluginOutput; | ShowPluginOutputToggleItem.Checked = config.showPluginOutput; | ||||
AutoStartupItem.Checked = AutoStartup.Check(); | AutoStartupItem.Checked = AutoStartup.Check(); | ||||
ProtocolHandlerItem.Checked = ProtocolHandler.Check(); | |||||
onlinePACItem.Checked = onlinePACItem.Enabled && config.useOnlinePac; | onlinePACItem.Checked = onlinePACItem.Enabled && config.useOnlinePac; | ||||
localPACItem.Checked = !onlinePACItem.Checked; | localPACItem.Checked = !onlinePACItem.Checked; | ||||
secureLocalPacUrlToggleItem.Checked = config.secureLocalPac; | secureLocalPacUrlToggleItem.Checked = config.secureLocalPac; | ||||
@@ -845,6 +848,16 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
MessageBox.Show(I18N.GetString("Failed to update registry")); | 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) | private void LocalPACItem_Click(object sender, EventArgs e) | ||||
@@ -114,6 +114,7 @@ | |||||
<Compile Include="Controller\LoggerExtension.cs" /> | <Compile Include="Controller\LoggerExtension.cs" /> | ||||
<Compile Include="Controller\Service\PACDaemon.cs" /> | <Compile Include="Controller\Service\PACDaemon.cs" /> | ||||
<Compile Include="Controller\Service\PipeServer.cs" /> | <Compile Include="Controller\Service\PipeServer.cs" /> | ||||
<Compile Include="Controller\System\ProtocolHandler.cs" /> | |||||
<Compile Include="Controller\System\Hotkeys\HotkeyCallbacks.cs" /> | <Compile Include="Controller\System\Hotkeys\HotkeyCallbacks.cs" /> | ||||
<Compile Include="Encryption\AEAD\AEADEncryptor.cs" /> | <Compile Include="Encryption\AEAD\AEADEncryptor.cs" /> | ||||
<Compile Include="Encryption\AEAD\AEADMbedTLSEncryptor.cs" /> | <Compile Include="Encryption\AEAD\AEADMbedTLSEncryptor.cs" /> | ||||