|
|
@@ -1,20 +1,19 @@ |
|
|
|
using Microsoft.Win32;
|
|
|
|
using NLog;
|
|
|
|
using Shadowsocks.Controller;
|
|
|
|
using Shadowsocks.Controller.Hotkeys;
|
|
|
|
using Shadowsocks.Util;
|
|
|
|
using Shadowsocks.View;
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.IO;
|
|
|
|
using System.IO.Pipes;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Net;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using System.Windows.Forms;
|
|
|
|
using CommandLine;
|
|
|
|
using Microsoft.Win32;
|
|
|
|
using NLog;
|
|
|
|
using Shadowsocks.Controller;
|
|
|
|
using Shadowsocks.Controller.Hotkeys;
|
|
|
|
using Shadowsocks.Util;
|
|
|
|
using Shadowsocks.View;
|
|
|
|
|
|
|
|
namespace Shadowsocks
|
|
|
|
{
|
|
|
@@ -23,6 +22,7 @@ namespace Shadowsocks |
|
|
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
|
|
|
public static ShadowsocksController MainController { get; private set; }
|
|
|
|
public static MenuViewController MenuController { get; private set; }
|
|
|
|
public static CommandLineOption Options { get; private set; }
|
|
|
|
public static string[] Args { get; private set; }
|
|
|
|
|
|
|
|
// https://github.com/dotnet/runtime/issues/13051#issuecomment-510267727
|
|
|
@@ -35,6 +35,12 @@ namespace Shadowsocks |
|
|
|
[STAThread]
|
|
|
|
private static void Main(string[] args)
|
|
|
|
{
|
|
|
|
// store args for further use
|
|
|
|
Args = args;
|
|
|
|
Parser.Default.ParseArguments<CommandLineOption>(args)
|
|
|
|
.WithParsed(opt => Options = opt)
|
|
|
|
.WithNotParsed(e => e.Output());
|
|
|
|
|
|
|
|
Directory.SetCurrentDirectory(WorkingDirectory);
|
|
|
|
// todo: initialize the NLog configuartion
|
|
|
|
Model.NLogConfig.TouchAndApplyNLogConfig();
|
|
|
@@ -43,8 +49,6 @@ namespace Shadowsocks |
|
|
|
ServicePointManager.SecurityProtocol |=
|
|
|
|
SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
|
|
|
|
|
|
|
|
// store args for further use
|
|
|
|
Args = args;
|
|
|
|
// Check OS since we are using dual-mode socket
|
|
|
|
if (!Utils.IsWinVistaOrHigher())
|
|
|
|
{
|
|
|
@@ -65,8 +69,6 @@ namespace Shadowsocks |
|
|
|
}
|
|
|
|
string pipename = $"Shadowsocks\\{ExecutablePath.GetHashCode()}";
|
|
|
|
|
|
|
|
string addedUrl = null;
|
|
|
|
|
|
|
|
using (NamedPipeClientStream pipe = new NamedPipeClientStream(pipename))
|
|
|
|
{
|
|
|
|
bool pipeExist = false;
|
|
|
@@ -80,35 +82,19 @@ namespace Shadowsocks |
|
|
|
pipeExist = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: switch to better argv parser when it's getting complicate
|
|
|
|
List<string> alist = Args.ToList();
|
|
|
|
// check --open-url param
|
|
|
|
int urlidx = alist.IndexOf("--open-url") + 1;
|
|
|
|
if (urlidx > 0)
|
|
|
|
// --open-url exist, and no other instance, add it later
|
|
|
|
if (pipeExist && !string.IsNullOrWhiteSpace(Options.OpenUrl))
|
|
|
|
{
|
|
|
|
if (Args.Length <= urlidx)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --open-url exist, and no other instance, add it later
|
|
|
|
if (!pipeExist)
|
|
|
|
{
|
|
|
|
addedUrl = Args[urlidx];
|
|
|
|
}
|
|
|
|
// has other instance, send url via pipe then exit
|
|
|
|
else
|
|
|
|
{
|
|
|
|
byte[] b = Encoding.UTF8.GetBytes(Args[urlidx]);
|
|
|
|
byte[] opAddUrl = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(1));
|
|
|
|
byte[] blen = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(b.Length));
|
|
|
|
pipe.Write(opAddUrl, 0, 4); // opcode addurl
|
|
|
|
pipe.Write(blen, 0, 4);
|
|
|
|
pipe.Write(b, 0, b.Length);
|
|
|
|
pipe.Close();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
byte[] b = Encoding.UTF8.GetBytes(Options.OpenUrl);
|
|
|
|
byte[] opAddUrl = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(1));
|
|
|
|
byte[] blen = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(b.Length));
|
|
|
|
pipe.Write(opAddUrl, 0, 4); // opcode addurl
|
|
|
|
pipe.Write(blen, 0, 4);
|
|
|
|
pipe.Write(b, 0, b.Length);
|
|
|
|
pipe.Close();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// has another instance, and no need to communicate with it return
|
|
|
|
else if (pipeExist)
|
|
|
|
{
|
|
|
@@ -153,9 +139,9 @@ namespace Shadowsocks |
|
|
|
NamedPipeServer namedPipeServer = new NamedPipeServer();
|
|
|
|
Task.Run(() => namedPipeServer.Run(pipename));
|
|
|
|
namedPipeServer.AddUrlRequested += (_1, e) => MainController.AskAddServerBySSURL(e.Url);
|
|
|
|
if (!addedUrl.IsNullOrEmpty())
|
|
|
|
if (!string.IsNullOrWhiteSpace(Options.OpenUrl))
|
|
|
|
{
|
|
|
|
MainController.AskAddServerBySSURL(addedUrl);
|
|
|
|
MainController.AskAddServerBySSURL(Options.OpenUrl);
|
|
|
|
}
|
|
|
|
Application.Run();
|
|
|
|
}
|
|
|
|