private void ControlButton_Click(object sender, EventArgs e) { if (State == Objects.State.Waiting || State == Objects.State.Stopped) { if (ServerComboBox.SelectedIndex == -1) { MessageBox.Show(Utils.i18N.Translate("Please select an server first"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (ModeComboBox.SelectedIndex == -1) { MessageBox.Show(Utils.i18N.Translate("Please select an mode first"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } ToolStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = false; ControlButton.Text = "..."; StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting")}"; State = Objects.State.Starting; Task.Run(() => { MainController = new Controllers.MainController(); if (MainController.Start(ServerComboBox.SelectedItem as Objects.Server, ModeComboBox.SelectedItem as Objects.Mode)) { ControlButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Stop"); StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")}"; State = Objects.State.Started; } else { ToolStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Start"); StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Start failed")}"; State = Objects.State.Stopped; } }); } else { ControlButton.Enabled = false; ControlButton.Text = "..."; StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Stopping")}"; State = Objects.State.Stopping; Task.Run(() => { MainController.Stop(); ToolStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Start"); StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Stopped")}"; State = Objects.State.Stopped; }); } }
/// <summary> /// 启动 /// </summary> /// <param name="server">配置</param> /// <returns>是否成功</returns> public bool Start(Objects.Server server) { if (!File.Exists(String.Format("{0}\\Bin\\ShadowsocksR.exe", Directory.GetCurrentDirectory()))) { return(false); } File.WriteAllText("Data\\Last.json", Newtonsoft.Json.JsonConvert.SerializeObject(new Objects.Information.SSR() { server = server.Address, server_port = server.Port, password = server.Password, method = server.EncryptMethod, protocol = server.Protocol, protocol_param = server.ProtocolParam, obfs = server.OBFS, obfs_param = server.OBFSParam })); Instance = new Process(); Instance.StartInfo.WorkingDirectory = String.Format("{0}\\Bin", Directory.GetCurrentDirectory()); Instance.StartInfo.FileName = String.Format("{0}\\Bin\\ShadowsocksR.exe", Directory.GetCurrentDirectory()); Instance.StartInfo.Arguments = String.Format("-c \"{0}\\Data\\Last.json\" -u", Directory.GetCurrentDirectory()); Utils.Logging.Info(String.Format("SSR 启动参数:{0}", Instance.StartInfo.Arguments)); Instance.StartInfo.CreateNoWindow = true; Instance.StartInfo.RedirectStandardError = true; Instance.StartInfo.RedirectStandardInput = true; Instance.StartInfo.RedirectStandardOutput = true; Instance.StartInfo.UseShellExecute = false; Instance.EnableRaisingEvents = true; Instance.ErrorDataReceived += OnOutputDataReceived; Instance.OutputDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginErrorReadLine(); Instance.BeginOutputReadLine(); Instance.PriorityClass = ProcessPriorityClass.RealTime; for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { return(true); } if (State == Objects.State.Stopped) { Stop(); return(false); } } return(false); }
/// <summary> /// 停止 /// </summary> public void Stop() { if (!Instance.HasExited) { Instance.Kill(); State = Objects.State.Stopped; } }
/// <summary> /// 启动 /// </summary> /// <param name="server">服务器</param> /// <param name="mode">模式</param> /// <returns>是否启动成功</returns> public bool Start(Objects.Server server, Objects.Mode mode) { if (!File.Exists("bin\\Shadowsocks.exe")) { return false; } // 清理上一次的日志文件,防止淤积占用磁盘空间 if (Directory.Exists("logging")) { if (File.Exists("logging\\shadowsocks.log")) { File.Delete("logging\\shadowsocks.log"); } } Instance = MainController.GetProcess(); Instance.StartInfo.FileName = "bin\\Shadowsocks.exe"; Instance.StartInfo.Arguments = String.Format("-s {0} -p {1} -b 0.0.0.0 -l 2801 -m {2} -k \"{3}\" -u", server.Address, server.Port, server.EncryptMethod, server.Password); if (mode.BypassChina) { Instance.StartInfo.Arguments += " --acl default.acl"; } Instance.OutputDataReceived += OnOutputDataReceived; Instance.ErrorDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginOutputReadLine(); Instance.BeginErrorReadLine(); for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { return true; } if (State == Objects.State.Stopped) { Utils.Logging.Info("SS 进程启动失败"); Stop(); return false; } } Utils.Logging.Info("SS 进程启动超时"); Stop(); return false; }
/// <summary> /// 启动 /// </summary> /// <param name="server">配置</param> /// <returns>是否成功</returns> public bool Start(Objects.Server server) { if (!File.Exists(String.Format("{0}\\Bin\\Shadowsocks.exe", Directory.GetCurrentDirectory()))) { return(false); } Instance = new Process(); Instance.StartInfo.WorkingDirectory = String.Format("{0}\\Bin", Directory.GetCurrentDirectory()); Instance.StartInfo.FileName = String.Format("{0}\\Bin\\Shadowsocks.exe", Directory.GetCurrentDirectory()); Instance.StartInfo.Arguments = String.Format("-s {0} -p {1} -l 2810 -m {2} -k \"{3}\" -u", server.Address, server.Port, server.EncryptMethod, server.Password); Utils.Logging.Info(String.Format("SS 启动参数:{0}", Instance.StartInfo.Arguments)); Instance.StartInfo.CreateNoWindow = true; Instance.StartInfo.RedirectStandardError = true; Instance.StartInfo.RedirectStandardInput = true; Instance.StartInfo.RedirectStandardOutput = true; Instance.StartInfo.UseShellExecute = false; Instance.EnableRaisingEvents = true; Instance.ErrorDataReceived += OnOutputDataReceived; Instance.OutputDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginErrorReadLine(); Instance.BeginOutputReadLine(); Instance.PriorityClass = ProcessPriorityClass.RealTime; for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { return(true); } if (State == Objects.State.Stopped) { Stop(); return(false); } } return(false); }
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrWhiteSpace(e.Data)) { File.AppendAllText("logging\\redirector.log", String.Format("{0}\r\n", e.Data)); if (State == Objects.State.Starting) { if (Instance.HasExited) { State = Objects.State.Stopped; } else if (e.Data.Contains("Started")) { State = Objects.State.Started; } else if (e.Data.Contains("Failed") || e.Data.Contains("Unable")) { State = Objects.State.Stopped; } } else if (State == Objects.State.Started) { if (e.Data.StartsWith("[Application][Bandwidth]")) { var splited = e.Data.Replace("[Application][Bandwidth]", "").Trim().Split(','); if (splited.Length == 2) { var uploadSplited = splited[0].Split(':'); var downloadSplited = splited[1].Split(':'); if (uploadSplited.Length == 2 && downloadSplited.Length == 2) { if (long.TryParse(uploadSplited[1], out long upload) && long.TryParse(downloadSplited[1], out long download)) { Task.Run(() => OnBandwidthUpdated(upload, download)); } } } } } } }
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrEmpty(e.Data)) { File.AppendAllText("logging\\tun2socks.log", String.Format("{0}\r\n", e.Data.Trim())); if (State == Objects.State.Starting) { if (e.Data.Contains("Running")) { State = Objects.State.Started; } else if (e.Data.Contains("failed") || e.Data.Contains("invalid vconfig file")) { State = Objects.State.Stopped; } } } }
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrEmpty(e.Data)) { File.AppendAllText("Logging\\shadowsocksr.log", String.Format("{0}\r\n", e.Data.Trim())); if (State == Objects.State.Starting) { if (e.Data.Contains("listening at")) { State = Objects.State.Started; } else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage")) { State = Objects.State.Stopped; } } } }
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrWhiteSpace(e.Data)) { File.AppendAllText("logging\\redirector.log", String.Format("{0}\r\n", e.Data)); if (State == Objects.State.Starting) { if (Instance.HasExited) { State = Objects.State.Stopped; } else if (e.Data.Contains("Started")) { State = Objects.State.Started; } else if (e.Data.Contains("Failed") || e.Data.Contains("Unable")) { State = Objects.State.Stopped; } } } }
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrWhiteSpace(e.Data)) { File.AppendAllText("logging\\v2ray.log", $"{e.Data}\r\n"); if (State == Objects.State.Starting) { if (Instance.HasExited) { State = Objects.State.Stopped; } else if (e.Data.Contains("started")) { State = Objects.State.Started; } else if (e.Data.Contains("config file not readable") || e.Data.Contains("failed to")) { State = Objects.State.Stopped; } } } }
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrWhiteSpace(e.Data)) { File.AppendAllText("logging\\shadowsocksr.log", $"{e.Data}\r\n"); if (State == Objects.State.Starting) { if (Instance.HasExited) { State = Objects.State.Stopped; } else if (e.Data.Contains("listening at")) { State = Objects.State.Started; } else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage")) { State = Objects.State.Stopped; } } } }
private void ExitToolStripButton_Click(object sender, EventArgs e) { Global.Settings.ServerComboBoxSelectedIndex = ServerComboBox.SelectedIndex; Global.Settings.ModeComboBoxSelectedIndex = ModeComboBox.SelectedIndex; Utils.Configuration.Save(); if (State != Objects.State.Waiting && State != Objects.State.Stopped) { MessageBox.Show(Utils.i18N.Translate("Please press Stop button first"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); this.Visible = true; this.ShowInTaskbar = true; // 显示在系统任务栏 this.WindowState = FormWindowState.Normal; // 还原窗体 this.NotifyIcon.Visible = true; // 托盘图标隐藏 return; } State = Objects.State.Terminating; this.NotifyIcon.Visible = false; this.Close(); this.Dispose(); System.Environment.Exit(System.Environment.ExitCode); }
/// <summary> /// 设置绕行规则 /// </summary> public bool SetupBypass() { // 让服务器 IP 走直连 foreach (var address in ServerAddresses) { if (!IPAddress.IsLoopback(address)) { NativeMethods.CreateRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } // 处理全局绕过 IP foreach (var ip in Global.BypassIPs) { var info = ip.Split('/'); var address = IPAddress.Parse(info[0]); if (!IPAddress.IsLoopback(address)) { NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } if (SavedMode.Type == 2) // 处理仅规则内走直连 { // 创建默认路由 if (!NativeMethods.CreateRoute("0.0.0.0", 0, Global.TUNTAP.Gateway.ToString(), Global.TUNTAP.Index, 10)) { State = Objects.State.Stopped; foreach (var address in ServerAddresses) { NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } return(false); } foreach (var ip in SavedMode.Rule) { var info = ip.Split('/'); if (info.Length == 2) { if (int.TryParse(info[1], out var prefix)) { NativeMethods.CreateRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } } } else if (SavedMode.Type == 1) // 处理仅规则内走代理 { foreach (var ip in SavedMode.Rule) { var info = ip.Split('/'); if (info.Length == 2) { if (int.TryParse(info[1], out var prefix)) { NativeMethods.CreateRoute(info[0], prefix, Global.TUNTAP.Gateway.ToString(), Global.TUNTAP.Index); } } } } return(true); }
private void ControlButton_Click(object sender, EventArgs e) { if (State == Objects.State.Waiting || State == Objects.State.Stopped) { // 当前ServerComboBox中至少有一项 if (ServerComboBox.SelectedIndex == -1) { MessageBox.Show(Utils.i18N.Translate("Please select a server first"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // 当前ModeComboBox中至少有一项 if (ModeComboBox.SelectedIndex == -1) { MessageBox.Show(Utils.i18N.Translate("Please select an mode first"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } ToolStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false; ControlButton.Text = "..."; StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting")}"; State = Objects.State.Starting; Task.Run(() => { var server = ServerComboBox.SelectedItem as Objects.Server; var mode = ModeComboBox.SelectedItem as Objects.Mode; MainController = new Controllers.MainController(); if (MainController.Start(server, mode)) { UsedBandwidthLabel.Visible = UploadSpeedLabel.Visible = DownloadSpeedLabel.Visible = true; ControlButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Stop"); StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")}"; State = Objects.State.Started; } else { ToolStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Start"); StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Start failed")}"; State = Objects.State.Stopped; } }); } else { ControlButton.Enabled = false; ControlButton.Text = "..."; StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Stopping")}"; State = Objects.State.Stopping; Task.Run(() => { var server = ServerComboBox.SelectedItem as Objects.Server; var mode = ModeComboBox.SelectedItem as Objects.Mode; MainController.Stop(); //if (mode.Type == 0) //{ LastUploadBandwidth = 0; LastDownlaodBandwidth = 0; UploadSpeedLabel.Text = "↑: 0 KB/s"; DownloadSpeedLabel.Text = "↓: 0 KB/s"; UsedBandwidthLabel.Text = $"{Utils.i18N.Translate("Used")}{Utils.i18N.Translate(": ")}0 KB"; //UsedBandwidthLabel.Visible = UploadSpeedLabel.Visible = DownloadSpeedLabel.Visible = false; UsedBandwidthLabel.Visible = UploadSpeedLabel.Visible = DownloadSpeedLabel.Visible = true; //} ToolStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Start"); StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Stopped")}"; State = Objects.State.Stopped; TestServer(); }); } }
private void ControlButton_Click(object sender, EventArgs e) { if (State == Objects.State.Waiting || State == Objects.State.Stopped) { // 当前ServerComboBox中至少有一项 if (ServerComboBox.SelectedIndex == -1) { MessageBox.Show(Utils.i18N.Translate("Please select a server first"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // 当前ModeComboBox中至少有一项 if (ModeComboBox.SelectedIndex == -1) { MessageBox.Show(Utils.i18N.Translate("Please select an mode first"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false; ControlButton.Text = "..."; StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting")}"; State = Objects.State.Starting; Task.Run(() => { var server = ServerComboBox.SelectedItem as Objects.Server; var mode = ModeComboBox.SelectedItem as Objects.Mode; MainController = new Controllers.MainController(); if (MainController.Start(server, mode)) { if (mode.Type == 0) { UsedBandwidthLabel.Visible = UploadSpeedLabel.Visible = DownloadSpeedLabel.Visible = true; MainController.pNFController.OnBandwidthUpdated += OnBandwidthUpdated; } ControlButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Stop"); if (mode.Type != 3 && mode.Type != 5) { if (server.Type != "Socks5") { if (Global.Settings.LocalAddress == "0.0.0.0") { StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")} ({Utils.i18N.Translate("Allow other Devices to connect")} Socks5 {Utils.i18N.Translate("Local Port")}{Utils.i18N.Translate(": ")}{Global.Settings.Socks5LocalPort})"; } else { StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")} (Socks5 {Utils.i18N.Translate("Local Port")}{Utils.i18N.Translate(": ")}{Global.Settings.Socks5LocalPort}{")"}"; } } else { StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")}"; } } else { if (server.Type != "Socks5") { if (Global.Settings.LocalAddress == "0.0.0.0") { StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")} ({Utils.i18N.Translate("Allow other Devices to connect")} Socks5 {Utils.i18N.Translate("Local Port")}{Utils.i18N.Translate(": ")}{Global.Settings.Socks5LocalPort} | HTTP {Utils.i18N.Translate("Local Port")}{Utils.i18N.Translate(": ")}{Global.Settings.HTTPLocalPort}{")"}"; } else { StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")} (Socks5 {Utils.i18N.Translate("Local Port")}{Utils.i18N.Translate(": ")}{Global.Settings.Socks5LocalPort} | HTTP {Utils.i18N.Translate("Local Port")}{Utils.i18N.Translate(": ")}{Global.Settings.HTTPLocalPort})"; } } else { if (Global.Settings.LocalAddress == "0.0.0.0") { StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")} ({Utils.i18N.Translate("Allow other Devices to connect")} HTTP {Utils.i18N.Translate("Local Port")}{Utils.i18N.Translate(": ")}{Global.Settings.HTTPLocalPort}{")"}"; } else { StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Started")} (HTTP {Utils.i18N.Translate("Local Port")}{Utils.i18N.Translate(": ")}{Global.Settings.HTTPLocalPort})"; } } } State = Objects.State.Started; } else { MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Start"); StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Start failed")}"; State = Objects.State.Stopped; } }); } else { ControlButton.Enabled = false; ControlButton.Text = "..."; StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Stopping")}"; State = Objects.State.Stopping; Task.Run(() => { var server = ServerComboBox.SelectedItem as Objects.Server; var mode = ModeComboBox.SelectedItem as Objects.Mode; MainController.Stop(); if (mode.Type == 0) { LastUploadBandwidth = 0; LastDownlaodBandwidth = 0; UploadSpeedLabel.Text = "↑: 0 KB/s"; DownloadSpeedLabel.Text = "↓: 0 KB/s"; UsedBandwidthLabel.Text = $"{Utils.i18N.Translate("Used")}{Utils.i18N.Translate(": ")}0 KB"; UsedBandwidthLabel.Visible = UploadSpeedLabel.Visible = DownloadSpeedLabel.Visible = false; } MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true; ControlButton.Text = Utils.i18N.Translate("Start"); StatusLabel.Text = $"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Stopped")}"; State = Objects.State.Stopped; TestServer(); }); } }
/// <summary> /// 设置绕行规则 /// </summary> public bool SetupBypass() { // 让服务器 IP 走直连 foreach (var address in ServerAddresses) { if (!IPAddress.IsLoopback(address)) { NativeMethods.CreateRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } // 处理模式的绕过中国 if (SavedMode.BypassChina) { using (var sr = new StringReader(Encoding.UTF8.GetString(Properties.Resources.CNIP))) { string text; while ((text = sr.ReadLine()) != null) { var info = text.Split('/'); NativeMethods.CreateRoute(info[0], int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } } // 处理全局绕过 IP foreach (var ip in Global.BypassIPs) { var info = ip.Split('/'); var address = IPAddress.Parse(info[0]); if (!IPAddress.IsLoopback(address)) { NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } if (SavedMode.Type == 2) // 处理仅规则内走直连 { // 创建默认路由 if (!NativeMethods.CreateRoute("0.0.0.0", 0, Global.TUNTAP.Gateway.ToString(), Global.TUNTAP.Index, 10)) { State = Objects.State.Stopped; foreach (var address in ServerAddresses) { NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } return(false); } foreach (var ip in SavedMode.Rule) { var info = ip.Split('/'); if (info.Length == 2) { if (int.TryParse(info[1], out var prefix)) { NativeMethods.CreateRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } } } else if (SavedMode.Type == 1) // 处理仅规则内走代理 { foreach (var ip in SavedMode.Rule) { var info = ip.Split('/'); if (info.Length == 2) { if (int.TryParse(info[1], out var prefix)) { NativeMethods.CreateRoute(info[0], prefix, Global.TUNTAP.Gateway.ToString(), Global.TUNTAP.Index); } } } } return(true); }
/// <summary> /// 启动 /// </summary> /// <param name="server">配置</param> /// <returns>是否成功</returns> public bool Start(Objects.Server server, Objects.Mode mode) { foreach (var proc in Process.GetProcessesByName("tun2socks")) { try { proc.Kill(); } catch (Exception) { // 跳过 } } if (!File.Exists("bin\\tun2socks.exe")) { return(false); } if (File.Exists("logging\\tun2socks.log")) { File.Delete("logging\\tun2socks.log"); } SavedMode = mode; SavedServer = server; Configure(); SetupBypass(); Instance = new Process(); Instance.StartInfo.WorkingDirectory = String.Format("{0}\\bin", Directory.GetCurrentDirectory()); Instance.StartInfo.FileName = String.Format("{0}\\bin\\tun2socks.exe", Directory.GetCurrentDirectory()); string dns; if (Global.TUNTAP.UseCustomDNS) { dns = ""; foreach (var value in Global.TUNTAP.DNS) { dns += value; dns += ','; } dns = dns.Trim(); dns = dns.Substring(0, dns.Length - 1); } else { pDNSController.Start(); dns = "127.0.0.1"; } if (Global.TUNTAP.UseFakeDNS) { dns += " -fakeDns"; } if (server.Type == "Socks5") { Instance.StartInfo.Arguments = String.Format("-proxyServer {0}:{1} -tunAddr {2} -tunMask {3} -tunGw {4} -tunDns {5}", server.Address, server.Port, Global.TUNTAP.Address, Global.TUNTAP.Netmask, Global.TUNTAP.Gateway, dns); } else { Instance.StartInfo.Arguments = String.Format("-proxyServer 127.0.0.1:{0} -tunAddr {1} -tunMask {2} -tunGw {3} -tunDns {4}", Global.Settings["Socks5Port"], Global.TUNTAP.Address, Global.TUNTAP.Netmask, Global.TUNTAP.Gateway, dns); } Instance.StartInfo.CreateNoWindow = true; Instance.StartInfo.RedirectStandardError = true; Instance.StartInfo.RedirectStandardInput = true; Instance.StartInfo.RedirectStandardOutput = true; Instance.StartInfo.UseShellExecute = false; Instance.EnableRaisingEvents = true; Instance.ErrorDataReceived += OnOutputDataReceived; Instance.OutputDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginErrorReadLine(); Instance.BeginOutputReadLine(); Instance.PriorityClass = ProcessPriorityClass.RealTime; for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { return(true); } if (State == Objects.State.Stopped) { Stop(); return(false); } } return(false); }
/// <summary> /// 启动 /// </summary> /// <param name="server">服务器</param> /// <param name="mode">模式</param> /// <returns>是否成功</returns> public bool Start(Objects.Server server, Objects.Mode mode) { if (!File.Exists("bin\\Redirector.exe")) { return(false); } if (File.Exists("logging\\redirector.log")) { File.Delete("logging\\redirector.log"); } // 生成驱动文件路径 var driver = String.Format("{0}\\drivers\\netfilter2.sys", Environment.SystemDirectory); // 检查驱动是否存在 if (!File.Exists(driver)) { // 生成系统版本 var version = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}"; // 检查系统版本并复制对应驱动 try { switch (version) { case "10.0": File.Copy("bin\\Win-10.sys", driver); Utils.Logging.Info("已复制 Win10 驱动"); break; case "6.3": case "6.2": File.Copy("bin\\Win-8.sys", driver); Utils.Logging.Info("已复制 Win8 驱动"); break; case "6.1": case "6.0": File.Copy("bin\\Win-7.sys", driver); Utils.Logging.Info("已复制 Win7 驱动"); break; default: Utils.Logging.Info($"不支持的系统版本:{version}"); return(false); } } catch (Exception e) { Utils.Logging.Info("复制驱动文件失败"); Utils.Logging.Info(e.ToString()); return(false); } // 注册驱动文件 var result = nfapinet.NFAPI.nf_registerDriver("netfilter2"); if (result != nfapinet.NF_STATUS.NF_STATUS_SUCCESS) { Utils.Logging.Info($"注册驱动失败,返回值:{result}"); return(false); } } try { var service = new ServiceController("netfilter2"); if (service.Status == ServiceControllerStatus.Stopped) { service.Start(); } } catch (Exception e) { Utils.Logging.Info(e.ToString()); var result = nfapinet.NFAPI.nf_registerDriver("netfilter2"); if (result != nfapinet.NF_STATUS.NF_STATUS_SUCCESS) { Utils.Logging.Info($"注册驱动失败,返回值:{result}"); return(false); } } var processes = ""; foreach (var proc in mode.Rule) { processes += proc; processes += ","; } processes = processes.Substring(0, processes.Length - 1); Instance = MainController.GetProcess(); Instance.StartInfo.FileName = "bin\\Redirector.exe"; Instance.StartInfo.Arguments = String.Format("-r 127.0.0.1:{0} -p \"{1}\"", Global.Settings["Socks5Port"], processes); if (server.Type == "Socks5") { var result = Utils.DNS.Lookup(server.Address); if (result == null) { Utils.Logging.Info("无法解析服务器 IP 地址"); return(false); } Instance.StartInfo.Arguments = String.Format("-r {0}:{1} -p \"{2}\"", result.ToString(), server.Port, processes); if (!String.IsNullOrWhiteSpace(server.Username) && !String.IsNullOrWhiteSpace(server.Password)) { Instance.StartInfo.Arguments += String.Format(" -username \"{0}\" -password \"{1}\"", server.Username, server.Password); } } Instance.OutputDataReceived += OnOutputDataReceived; Instance.ErrorDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginOutputReadLine(); Instance.BeginErrorReadLine(); for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { return(true); } if (State == Objects.State.Stopped) { Utils.Logging.Info("NF 进程启动失败"); Stop(); return(false); } } Utils.Logging.Info("NF 进程启动超时"); Stop(); return(false); }
private void ControlButton_Click(object sender, EventArgs e) { if (ServerComboBox.SelectedIndex != -1) { ControlButton.Enabled = false; StatusLabel.Text = Utils.MultiLanguage.Translate("Status") + Utils.MultiLanguage.Translate(": ") + Utils.MultiLanguage.Translate("Processing"); if (State == Objects.State.Waiting || State == Objects.State.Stopped) { State = Objects.State.Starting; ToolStrip.Enabled = ConfigurationGroupBox.Enabled = SettingsButton.Enabled = false; Task.Run(() => { var server = ServerComboBox.SelectedItem as Objects.Server; var mode = ModeComboBox.SelectedItem as Objects.Mode; try { // 查询服务器 IP 地址 var destination = Dns.GetHostAddressesAsync(server.Address); if (destination.Wait(1000)) { if (destination.Result.Length == 0) { State = Objects.State.Stopped; StatusLabel.Text = Utils.MultiLanguage.Translate("Status") + Utils.MultiLanguage.Translate(": ") + Utils.MultiLanguage.Translate("Resolve server IP failed"); ControlButton.Text = Utils.MultiLanguage.Translate("Start"); ControlButton.Enabled = true; ToolStrip.Enabled = ConfigurationGroupBox.Enabled = SettingsButton.Enabled = true; return; } ServerAddresses = destination.Result; } // 搜索出口 Utils.Configuration.SearchOutbounds(); // 启动实例 TUNTAPController = new Controllers.TUNTAPController(); if (TUNTAPController.Start(ServerComboBox.SelectedItem as Objects.Server)) { TUNTAPController.Instance.Exited += OnExited; if (server.Type == "Shadowsocks") { TUNTAPController.SSController.Instance.Exited += OnExited; } else if (server.Type == "ShadowsocksR") { TUNTAPController.SSRController.Instance.Exited += OnExited; } } else { State = Objects.State.Stopped; StatusLabel.Text = Utils.MultiLanguage.Translate("Status") + Utils.MultiLanguage.Translate(": ") + Utils.MultiLanguage.Translate("Starting failed"); ControlButton.Text = Utils.MultiLanguage.Translate("Start"); ControlButton.Enabled = true; ToolStrip.Enabled = ConfigurationGroupBox.Enabled = SettingsButton.Enabled = true; return; } // 处理模式的绕过中国 if (mode.BypassChina) { using (var sr = new StringReader(Encoding.UTF8.GetString(Properties.Resources.CNIP))) { string text; while ((text = sr.ReadLine()) != null) { var info = text.Split('/'); NativeMethods.CreateRoute(info[0], int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } } if (mode.Type == 0) // 处理仅规则内走直连 { // 创建默认路由 if (!NativeMethods.CreateRoute("0.0.0.0", 0, Global.TUNTAP.Gateway.ToString(), Global.TUNTAP.Index, 10)) { State = Objects.State.Stopped; foreach (var address in ServerAddresses) { NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } TUNTAPController.Stop(); StatusLabel.Text = Utils.MultiLanguage.Translate("Status") + Utils.MultiLanguage.Translate(": ") + Utils.MultiLanguage.Translate("Setting route table failed"); ControlButton.Text = Utils.MultiLanguage.Translate("Start"); ControlButton.Enabled = true; ToolStrip.Enabled = ConfigurationGroupBox.Enabled = SettingsButton.Enabled = true; return; } foreach (var ip in mode.Rule) { var info = ip.Split('/'); if (info.Length == 2) { if (int.TryParse(info[1], out var prefix)) { NativeMethods.CreateRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } } } else if (mode.Type == 1) // 处理仅规则内走代理 { foreach (var ip in mode.Rule) { var info = ip.Split('/'); if (info.Length == 2) { if (int.TryParse(info[1], out var prefix)) { NativeMethods.CreateRoute(info[0], prefix, Global.TUNTAP.Gateway.ToString(), Global.TUNTAP.Index); } } } } // 处理全局绕过 IP foreach (var ip in Global.BypassIPs) { var info = ip.Split('/'); var address = IPAddress.Parse(info[0]); if (!IPAddress.IsLoopback(address)) { NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } // 让服务器 IP 走直连 foreach (var address in ServerAddresses) { if (!IPAddress.IsLoopback(address)) { NativeMethods.CreateRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } // 设置状态:已启动 State = Objects.State.Started; // 速度显示线程 Task.Run(() => { var first = true; while (State == Objects.State.Started) { var stats = Global.TUNTAP.Adapter.GetIPv4Statistics(); if (first) { LastUplinkBandwidth = stats.BytesSent; LastDownlinkBandwidth = stats.BytesReceived; first = false; Thread.Sleep(1000); continue; } UplinkLabel.Text = String.Format("↑{0}{1}/s", Utils.MultiLanguage.Translate(": "), Utils.Util.ComputeBandwidth(stats.BytesSent - UplinkBandwidth)); DownlinkLabel.Text = String.Format("↓{0}{1}/s", Utils.MultiLanguage.Translate(": "), Utils.Util.ComputeBandwidth(stats.BytesReceived - DownlinkBandwidth)); UsedBandwidthLabel.Text = String.Format("{0}{1}{2}", Utils.MultiLanguage.Translate("Used"), Utils.MultiLanguage.Translate(": "), Utils.Util.ComputeBandwidth(stats.BytesSent + stats.BytesReceived - LastUplinkBandwidth - LastDownlinkBandwidth)); UplinkBandwidth = stats.BytesSent; DownlinkBandwidth = stats.BytesReceived; Thread.Sleep(1000); } }); StatusLabel.Text = Utils.MultiLanguage.Translate("Status") + Utils.MultiLanguage.Translate(": ") + Utils.MultiLanguage.Translate("Started"); ControlButton.Text = Utils.MultiLanguage.Translate("Stop"); ControlButton.Enabled = true; } catch (Exception ex) { Utils.Logging.Info(ex.ToString()); if (TUNTAPController != null) { TUNTAPController.Stop(); } StatusLabel.Text = Utils.MultiLanguage.Translate("Status") + Utils.MultiLanguage.Translate(": ") + Utils.MultiLanguage.Translate("Unknown error"); ControlButton.Text = Utils.MultiLanguage.Translate("Start"); ControlButton.Enabled = true; ToolStrip.Enabled = ConfigurationGroupBox.Enabled = SettingsButton.Enabled = true; return; } }); } else { State = Objects.State.Stopping; Task.Run(() => { var server = ServerComboBox.SelectedItem as Objects.Server; var mode = ModeComboBox.SelectedItem as Objects.Mode; TUNTAPController.Stop(); foreach (var address in ServerAddresses) { if (!IPAddress.IsLoopback(address)) { NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } if (mode.BypassChina) { using (var sr = new StringReader(Encoding.UTF8.GetString(Properties.Resources.CNIP))) { string text; while ((text = sr.ReadLine()) != null) { var info = text.Split('/'); NativeMethods.DeleteRoute(info[0], int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } } if (mode.Type == 0) { NativeMethods.DeleteRoute("0.0.0.0", 0, Global.TUNTAP.Gateway.ToString(), Global.TUNTAP.Index, 10); foreach (var ip in mode.Rule) { var info = ip.Split('/'); if (info.Length == 2) { if (int.TryParse(info[1], out var prefix)) { NativeMethods.DeleteRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } } } else if (mode.Type == 1) { foreach (var ip in mode.Rule) { var info = ip.Split('/'); if (info.Length == 2) { if (int.TryParse(info[1], out var prefix)) { NativeMethods.DeleteRoute(info[0], prefix, Global.TUNTAP.Gateway.ToString(), Global.TUNTAP.Index); } } } } foreach (var ip in Global.BypassIPs) { var info = ip.Split('/'); var address = IPAddress.Parse(info[0]); if (!IPAddress.IsLoopback(address)) { NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); } } State = Objects.State.Stopped; StatusLabel.Text = Utils.MultiLanguage.Translate("Status") + Utils.MultiLanguage.Translate(": ") + Utils.MultiLanguage.Translate("Stopped"); ControlButton.Text = Utils.MultiLanguage.Translate("Start"); ToolStrip.Enabled = ConfigurationGroupBox.Enabled = SettingsButton.Enabled = ControlButton.Enabled = true; }); } } else { MessageBox.Show(Utils.MultiLanguage.Translate("Please select an server"), Utils.MultiLanguage.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); } }
/// <summary> /// 启动 /// </summary> /// <param name="server">服务器</param> /// <param name="mode">模式</param> /// <returns>是否启动成功</returns> public bool Start(Objects.Server server, Objects.Mode mode) { foreach (var proc in Process.GetProcessesByName("ShadowsocksR")) { try { proc.Kill(); } catch (Exception) { // 跳过 } } if (!File.Exists("bin\\ShadowsocksR.exe")) { return(false); } if (!Directory.Exists("data")) { Directory.CreateDirectory("data"); } File.WriteAllText("data\\last.json", Newtonsoft.Json.JsonConvert.SerializeObject(new Objects.Information.SSR() { server = server.Address, server_port = server.Port, password = server.Password, method = server.EncryptMethod, protocol = server.Protocol, protocol_param = server.ProtocolParam, obfs = server.OBFS, obfs_param = server.OBFSParam })); // 清理上一次的日志文件,防止淤积占用磁盘空间 if (Directory.Exists("logging")) { if (File.Exists("logging\\shadowsocksr.log")) { File.Delete("logging\\shadowsocksr.log"); } } Instance = MainController.GetProcess(); Instance.StartInfo.FileName = "bin\\ShadowsocksR.exe"; Instance.StartInfo.Arguments = "-c ..\\data\\last.json -u"; if (mode.BypassChina) { Instance.StartInfo.Arguments += " --acl default.acl"; } Instance.OutputDataReceived += OnOutputDataReceived; Instance.ErrorDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginOutputReadLine(); Instance.BeginErrorReadLine(); for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { if (File.Exists("data\\last.json")) { File.Delete("data\\last.json"); } return(true); } if (State == Objects.State.Stopped) { Utils.Logging.Info("SSR 进程启动失败"); Stop(); return(false); } } Utils.Logging.Info("SSR 进程启动超时"); Stop(); return(false); }
/// <summary> /// 启动 /// </summary> /// <param name="server">服务器</param> /// <param name="mode">模式</param> /// <returns>是否启动成功</returns> public bool Start(Objects.Server server, Objects.Mode mode) { if (!File.Exists("bin\\v2ray.exe") || !File.Exists("bin\\v2ctl.exe")) { return(false); } if (!Directory.Exists("data")) { Directory.CreateDirectory("data"); } File.WriteAllText("data\\last.json", Newtonsoft.Json.JsonConvert.SerializeObject(new Objects.Information.VMess.Config() { inbounds = new List <Objects.Information.VMess.Inbounds>() { new Objects.Information.VMess.Inbounds() { settings = new Objects.Information.VMess.InboundSettings() } }, outbounds = new List <Objects.Information.VMess.Outbounds>() { new Objects.Information.VMess.Outbounds() { settings = new Objects.Information.VMess.OutboundSettings() { vnext = new List <Objects.Information.VMess.VNext>() { new Objects.Information.VMess.VNext() { address = server.Address, port = server.Port, users = new List <Objects.Information.VMess.User> { new Objects.Information.VMess.User() { id = server.UserID, alterId = server.AlterID, security = server.EncryptMethod } } } } }, streamSettings = new Objects.Information.VMess.StreamSettings() { network = server.TransferProtocol, security = server.TLSSecure == true ? "tls" : "", wsSettings = server.TransferProtocol == "ws" ? new Objects.Information.VMess.WebSocketSettings() { path = server.Path == "" ? "/" : server.Path, headers = new Objects.Information.VMess.WSHeaders() { Host = server.Host == "" ? server.Address : server.Host } } : null, tcpSettings = server.FakeType == "http" ? new Objects.Information.VMess.TCPSettings() { header = new Objects.Information.VMess.TCPHeaders() { type = server.FakeType, request = new Objects.Information.VMess.TCPRequest() { path = server.Path == "" ? "/" : server.Path, headers = new Objects.Information.VMess.TCPRequestHeaders() { Host = server.Host == "" ? server.Address : server.Host } } } } : null, kcpSettings = server.TransferProtocol == "kcp" ? new Objects.Information.VMess.KCPSettings() { header = new Objects.Information.VMess.TCPHeaders() { type = server.FakeType } } : null, quicSettings = server.TransferProtocol == "quic" ? new Objects.Information.VMess.QUICSettings() { security = server.QUICSecurity, key = server.QUICSecret, header = new Objects.Information.VMess.TCPHeaders() { type = server.FakeType } } : null, httpSettings = server.TransferProtocol == "h2" ? new Objects.Information.VMess.HTTPSettings() { host = server.Host == "" ? server.Address : server.Host, path = server.Path == "" ? "/" : server.Path } : null, tlsSettings = new Objects.Information.VMess.TLSSettings() }, mux = new Objects.Information.VMess.OutboundMux() } }, routing = new Objects.Information.VMess.Routing() })); // 清理上一次的日志文件,防止淤积占用磁盘空间 if (Directory.Exists("logging")) { if (File.Exists("logging\\v2ray.log")) { File.Delete("logging\\v2ray.log"); } } Instance = MainController.GetProcess(); Instance.StartInfo.FileName = "bin\\v2ray.exe"; Instance.StartInfo.Arguments = "-config ..\\data\\last.json"; Instance.OutputDataReceived += OnOutputDataReceived; Instance.ErrorDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginOutputReadLine(); Instance.BeginErrorReadLine(); for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { if (File.Exists("data\\last.json")) { File.Delete("data\\last.json"); } return(true); } if (State == Objects.State.Stopped) { Utils.Logging.Info("V2Ray 进程启动失败"); Stop(); return(false); } } Utils.Logging.Info("V2Ray 进程启动超时"); Stop(); return(false); }
/// <summary> /// 启动 /// </summary> /// <param name="server">服务器</param> /// <param name="mode">模式</param> /// <returns>是否启动成功</returns> public bool Start(Objects.Server server, Objects.Mode mode) { if (!File.Exists("bin\\Shadowsocks.exe")) { return(false); } // 清理上一次的日志文件,防止淤积占用磁盘空间 if (Directory.Exists("logging")) { if (File.Exists("logging\\shadowsocks.log")) { File.Delete("logging\\shadowsocks.log"); } } Instance = MainController.GetProcess(); Instance.StartInfo.FileName = "bin\\Shadowsocks.exe"; if (!String.IsNullOrWhiteSpace(server.OBFS) && !String.IsNullOrWhiteSpace(server.OBFSParam)) { Instance.StartInfo.Arguments = $"-s {server.Address} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u --plugin {server.OBFS} --plugin-opts \"{server.OBFSParam}\""; } else { Instance.StartInfo.Arguments = $"-s {server.Address} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u"; } if (mode.BypassChina) { Instance.StartInfo.Arguments += " --acl default.acl"; } Instance.OutputDataReceived += OnOutputDataReceived; Instance.ErrorDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginOutputReadLine(); Instance.BeginErrorReadLine(); for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { return(true); } if (State == Objects.State.Stopped) { Utils.Logging.Info("SS 进程启动失败"); Stop(); return(false); } } Utils.Logging.Info("SS 进程启动超时"); Stop(); return(false); }
/// <summary> /// 启动 /// </summary> /// <param name="server">服务器</param> /// <param name="mode">模式</param> /// <returns>是否启动成功</returns> public bool Start(Objects.Server server, Objects.Mode mode) { foreach (var proc in Process.GetProcessesByName("Shadowsocks")) { try { proc.Kill(); } catch (Exception) { // 跳过 } } if (!File.Exists("bin\\Shadowsocks.exe")) { return(false); } // 清理上一次的日志文件,防止淤积占用磁盘空间 if (Directory.Exists("logging")) { if (File.Exists("logging\\shadowsocks.log")) { File.Delete("logging\\shadowsocks.log"); } } Instance = MainController.GetProcess(); Instance.StartInfo.FileName = "bin\\Shadowsocks.exe"; if (!String.IsNullOrWhiteSpace(server.OBFS) && !String.IsNullOrWhiteSpace(server.OBFSParam)) { Instance.StartInfo.Arguments = String.Format("-s {0} -p {1} -b 0.0.0.0 -l 2801 -m {2} -k \"{3}\" -u --plugin {4} --plugin-opts \"{5}\"", server.Address, server.Port, server.EncryptMethod, server.Password, server.OBFS, server.OBFSParam); } else { Instance.StartInfo.Arguments = String.Format("-s {0} -p {1} -b 0.0.0.0 -l 2801 -m {2} -k \"{3}\" -u", server.Address, server.Port, server.EncryptMethod, server.Password); } if (mode.BypassChina) { Instance.StartInfo.Arguments += " --acl default.acl"; } Instance.OutputDataReceived += OnOutputDataReceived; Instance.ErrorDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginOutputReadLine(); Instance.BeginErrorReadLine(); for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { return(true); } if (State == Objects.State.Stopped) { Utils.Logging.Info("SS 进程启动失败"); Stop(); return(false); } } Utils.Logging.Info("SS 进程启动超时"); Stop(); return(false); }
/// <summary> /// 启动 /// </summary> /// <param name="server">配置</param> /// <returns>是否成功</returns> public bool Start(Objects.Server server) { if (server.Type == "Shadowsocks") { SSController = new SSController(); if (!SSController.Start(server)) { return(false); } } else if (server.Type == "ShadowsocksR") { SRController = new SRController(); if (!SRController.Start(server)) { return(false); } } Instance = new Process(); Instance.StartInfo.WorkingDirectory = String.Format("{0}\\Bin", Directory.GetCurrentDirectory()); Instance.StartInfo.FileName = String.Format("{0}\\Bin\\tun2socks.exe", Directory.GetCurrentDirectory()); var dns = "1.1.1.1"; if (Global.TUNTAP.UseCustomDNS) { dns = ""; foreach (var value in Global.TUNTAP.DNS) { dns += value; dns += ','; } dns = dns.Trim(); dns = dns.Substring(0, dns.Length - 1); } if (Global.TUNTAP.UseFakeDNS) { dns = dns + " -fakeDns"; } if (server.Type == "Socks5") { Instance.StartInfo.Arguments = String.Format("-proxyServer {0}:{1} -tunAddr {2} -tunMask {3} -tunGw {4} -tunDns {5}", server.Address, server.Port, Global.TUNTAP.Address, Global.TUNTAP.Netmask, Global.TUNTAP.Gateway, dns); } else if (server.Type == "VMess") { var data = new Objects.Information.Main(); var outbound = new Objects.Information.Outbound() { tag = "defaultOutbound" }; if (server.Type == "VMess") { outbound.protocol = "vmess"; var settings = new Objects.Information.Protocol.Outbound.VMess(); settings.vnext.Add(new Objects.Information.Protocol.Outbound.VMessServer() { address = server.Address, port = server.Port, users = new List <Objects.Information.Protocol.Outbound.VMessUser>() { new Objects.Information.Protocol.Outbound.VMessUser() { id = server.UserID, alterId = server.AlterID, security = "auto" } } }); outbound.settings = settings; outbound.streamSettings = new Objects.Information.OutboundStream(); outbound.streamSettings.network = server.TransferProtocol; outbound.streamSettings.security = server.TLSSecure ? "tls" : "none"; switch (server.TransferProtocol) { case "tcp": outbound.streamSettings.network = "tcp"; if (server.FakeType == "http") { var tcpSettings = new Objects.Information.OutboundStreamTCP() { header = new Objects.Information.OutboundStreamTCPHTTPHeader() { request = new Objects.Information.OutboundStreamTCPHTTPRequestHeader() { headers = new Dictionary <string, List <string> >() { { "Host", new List <string>() { server.Host } } } } } }; } break; case "kcp": outbound.streamSettings.network = "kcp"; outbound.streamSettings.kcpSettings = new Objects.Information.OutboundStreamKCP() { header = new Dictionary <string, string>() { { "type", server.FakeType } } }; break; case "ws": outbound.streamSettings.network = "ws"; var wsSettings = new Objects.Information.OutboundStreamWebSocket() { path = server.Path }; if (server.Host != "") { wsSettings.headers.Add("Host", server.Host); } outbound.streamSettings.wsSettings = wsSettings; break; case "http": outbound.streamSettings.network = "http"; var httpSettings = new Objects.Information.OutboundStreamHTTP2(); if (server.Host != "") { httpSettings.host = new List <string>() { server.Host }; } httpSettings.path = server.Path; outbound.streamSettings.httpSettings = httpSettings; break; case "quic": outbound.streamSettings.network = "quic"; outbound.streamSettings.quicSettings = new Objects.Information.OutboundStreamQUIC() { header = new Dictionary <string, string>() { { "type", server.FakeType } }, security = server.QUICSecurity, key = server.QUICSecret }; break; default: outbound.streamSettings.network = "tcp"; break; } } data.outbounds.Add(outbound); File.WriteAllText("Data\\Last.json", Newtonsoft.Json.JsonConvert.SerializeObject(data)); Instance.StartInfo.Arguments = String.Format("-proxyType v2ray -vconfig \"{0}\" -tunAddr {1} -tunMask {2} -tunGw {3} -tunDns {4}", String.Format("{0}\\Data\\Last.json", Directory.GetCurrentDirectory()), Global.TUNTAP.Address, Global.TUNTAP.Netmask, Global.TUNTAP.Gateway, dns); } else { Instance.StartInfo.Arguments = String.Format("-proxyServer 127.0.0.1:2810 -tunAddr {0} -tunMask {1} -tunGw {2} -tunDns {3}", Global.TUNTAP.Address, Global.TUNTAP.Netmask, Global.TUNTAP.Gateway, dns); } Instance.StartInfo.CreateNoWindow = true; Instance.StartInfo.RedirectStandardError = true; Instance.StartInfo.RedirectStandardInput = true; Instance.StartInfo.RedirectStandardOutput = true; Instance.StartInfo.UseShellExecute = false; Instance.EnableRaisingEvents = true; Instance.ErrorDataReceived += OnOutputDataReceived; Instance.OutputDataReceived += OnOutputDataReceived; State = Objects.State.Starting; Instance.Start(); Instance.BeginErrorReadLine(); Instance.BeginOutputReadLine(); for (int i = 0; i < 1000; i++) { Thread.Sleep(10); if (State == Objects.State.Started) { return(true); } if (State == Objects.State.Stopped) { Stop(); return(false); } } return(false); }