From b916412957da73374b3c7b030e220a9e2646d52c Mon Sep 17 00:00:00 2001 From: ProxySU Date: Wed, 19 Aug 2020 20:33:58 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BANaiveProxy=E6=B7=BB=E5=8A=A0=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E8=BF=87=E7=A8=8B=E6=98=BE=E7=A4=BA=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProxySU/MainWindow.xaml | 52 +- ProxySU/MainWindow.xaml.cs | 1487 +++++++++++++++++++++++++----------- ProxySU/bin/Beta/Beta.zip | Bin 495061 -> 496729 bytes 3 files changed, 1067 insertions(+), 472 deletions(-) diff --git a/ProxySU/MainWindow.xaml b/ProxySU/MainWindow.xaml index cbbaefe..8605dea 100644 --- a/ProxySU/MainWindow.xaml +++ b/ProxySU/MainWindow.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ProxySU" mc:Ignorable="d" - Title="ProxySU" Height="600" Width="900"> + Title="ProxySU" Height="600" Width="530"> @@ -49,7 +49,7 @@ - + @@ -69,11 +69,11 @@ - - - + + + - + @@ -84,27 +84,28 @@ - + - - + + - - - - + + + + - - - - - - + + + + + + - - + + + @@ -176,8 +177,8 @@ - - + + @@ -316,10 +317,11 @@ + - diff --git a/ProxySU/MainWindow.xaml.cs b/ProxySU/MainWindow.xaml.cs index fade9ff..a0da549 100644 --- a/ProxySU/MainWindow.xaml.cs +++ b/ProxySU/MainWindow.xaml.cs @@ -45,6 +45,15 @@ namespace ProxySU //ReceiveConfigurationParameters[7]----伪装网站 //public static ConnectionInfo ConnectionInfo; static bool testDomain = false; //设置标识--域名是否需要检测解析,初始化为不需要 + static string sshShellCommand;//定义保存执行的命令 + //sshShellCommand = ; + //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + + static string currentShellCommandResult;//定义Shell命令执行结果保存变量 + //currentShellCommandResult = ; + //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + public MainWindow() { InitializeComponent(); @@ -235,6 +244,7 @@ namespace ProxySU string sshHostName = TextBoxHost.Text.ToString(); int sshPort = int.Parse(TextBoxPort.Text); string sshUser = TextBoxUserName.Text.ToString(); + if (RadioButtonPasswordLogin.IsChecked == true && string.IsNullOrEmpty(PasswordBoxHostPassword.Password) == true) { MessageBox.Show("登录密码为必填项,不能为空"); @@ -320,6 +330,8 @@ namespace ProxySU return connectionInfo; } + #region V2Ray相关 + //打开v2ray模板设置窗口 private void ButtonTemplateConfiguration_Click(object sender, RoutedEventArgs e) { @@ -1344,269 +1356,10 @@ namespace ProxySU #endregion } - - - //上传配置文件 - private void UploadConfig(ConnectionInfo connectionInfo,string uploadConfig,string upLoadPath) - { - try - { - using (var sftpClient = new SftpClient(connectionInfo)) - { - sftpClient.Connect(); - //MessageBox.Show("sftp信息1" + sftpClient.ConnectionInfo.ServerVersion.ToString()); - //sftpClient.UploadFile(File.OpenRead("TemplateConfg\tcp_server_config.json"), "/etc/v2ray/config.json", true); - FileStream openUploadConfigFile = File.OpenRead(uploadConfig); - sftpClient.UploadFile(openUploadConfigFile, upLoadPath, true); - openUploadConfigFile.Close(); - //MessageBox.Show("sftp信息" + sftpClient.ConnectionInfo.ServerVersion.ToString()); - sftpClient.Disconnect(); - } - - } - catch (Exception ex2) - { - MessageBox.Show("sftp" + ex2.ToString()); - MessageBox.Show("sftp出现未知错误,上传文件失败,请重试!"); - return; - } - } - //下载配置文件 - private void DownloadConfig(ConnectionInfo connectionInfo, string downloadConfig,string downloadPath) - { - try - { - using (var sftpClient = new SftpClient(connectionInfo)) - { - sftpClient.Connect(); - //MessageBox.Show("sftp信息1" + sftpClient.ConnectionInfo.ServerVersion.ToString()); - FileStream createDownloadConfig = File.Open(downloadConfig, FileMode.Create); - sftpClient.DownloadFile(downloadPath, createDownloadConfig); - createDownloadConfig.Close(); - //MessageBox.Show("sftp信息" + sftpClient.ConnectionInfo.ServerVersion.ToString()); - sftpClient.Disconnect(); - } - - } - catch (Exception ex2) - { - MessageBox.Show("sftp" + ex2.ToString()); - MessageBox.Show("sftp出现未知错误,下载文件失败,请重试!"); - return; - } - } - - //更新UI显示内容 - Action updateAction = new Action(UpdateTextBlock); - private static void UpdateTextBlock(TextBlock textBlockName, ProgressBar progressBar, string currentStatus) - { - textBlockName.Text = currentStatus; - //if (currentStatus.Contains("正在登录远程主机") == true) - //{ - // progressBar.IsIndeterminate = true; - //} - //else if (currentStatus.Contains("主机登录成功") == true) - //{ - // progressBar.IsIndeterminate = true; - // //progressBar.Value = 100; - //} - //else if (currentStatus.Contains("检测系统是否符合安装要求") == true) - //{ - // progressBar.IsIndeterminate = true; - // //progressBar.Value = 100; - //} - //else if (currentStatus.Contains("布署中") == true) - //{ - // progressBar.IsIndeterminate = true; - // //progressBar.Value = 100; - //} - //else - if (currentStatus.Contains("成功") == true) - { - progressBar.IsIndeterminate = false; - progressBar.Value = 100; - } - else if(currentStatus.Contains("失败") == true || currentStatus.Contains("取消") == true || currentStatus.Contains("退出") == true) - { - progressBar.IsIndeterminate = false; - progressBar.Value = 0; - } - else - { - progressBar.IsIndeterminate = true; - //progressBar.Value = 0; - } - - - } - //检测系统内核是否符合安装要求 - private static bool DetectKernelVersion(string kernelVer) - { - string[] linuxKernelCompared = kernelVer.Split('.'); - if (int.Parse(linuxKernelCompared[0]) > 2) - { - //MessageBox.Show($"当前系统内核版本为{result.Result},符合安装要求!"); - return true; - } - else if (int.Parse(linuxKernelCompared[0]) < 2) - { - //MessageBox.Show($"当前系统内核版本为{result.Result},V2ray要求内核为2.6.23及以上。请升级内核再安装!"); - return false; - } - else if (int.Parse(linuxKernelCompared[0]) == 2) - { - if (int.Parse(linuxKernelCompared[1]) > 6) - { - //MessageBox.Show($"当前系统内核版本为{result.Result},符合安装要求!"); - return true; - } - else if (int.Parse(linuxKernelCompared[1]) < 6) - { - //MessageBox.Show($"当前系统内核版本为{result.Result},V2ray要求内核为2.6.23及以上。请升级内核再安装!"); - return false; - } - else if (int.Parse(linuxKernelCompared[1]) == 6) - { - if (int.Parse(linuxKernelCompared[2]) < 23) - { - //MessageBox.Show($"当前系统内核版本为{result.Result},V2ray要求内核为2.6.23及以上。请升级内核再安装!"); - return false; - } - else - { - //MessageBox.Show($"当前系统内核版本为{result.Result},符合安装要求!"); - return true; - } - - } - } - return false; - - } - - - //打开系统工具中的校对时间窗口 - private void ButtonProofreadTime_Click(object sender, RoutedEventArgs e) - { - ConnectionInfo connectionInfo = GenerateConnectionInfo(); - if (connectionInfo == null) - { - MessageBox.Show("远程主机连接信息有误,请检查"); - return; - } - - ProofreadTimeWindow proofreadTimeWindow = new ProofreadTimeWindow(); - ProofreadTimeWindow.ProfreadTimeReceiveConnectionInfo = connectionInfo; - - proofreadTimeWindow.ShowDialog(); - - } - //释放80/443端口 - private void ButtonClearOccupiedPorts_Click(object sender, RoutedEventArgs e) - { - MessageBoxResult dialogResult = MessageBox.Show("将强制停止占用80/443端口的程序?", "Stop application", MessageBoxButton.YesNo); - if (dialogResult== MessageBoxResult.No) - { - return; - } - - ConnectionInfo testconnect = GenerateConnectionInfo(); - try - { - using (var client = new SshClient(testconnect)) - { - client.Connect(); - - //检测是否运行在root权限下 - string testRootAuthority = client.RunCommand(@"id -u").Result; - if (testRootAuthority.Equals("0\n") == false) - { - MessageBox.Show("请使用具有root权限的账户登录主机!!"); - client.Disconnect(); - return; - } - string cmdTestPort; - string cmdResult; - cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; - cmdResult = client.RunCommand(cmdTestPort).Result; - //MessageBox.Show(cmdTestPort); - if (String.IsNullOrEmpty(cmdResult) ==false) - { - //MessageBox.Show(cmdResult); - string[] cmdResultArry443 = cmdResult.Split(' '); - //MessageBox.Show(cmdResultArry443[3]); - client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); - client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); - client.RunCommand($"kill -9 {cmdResultArry443[3]}"); - } - - cmdTestPort = @"lsof -n -P -i :80 | grep LISTEN"; - cmdResult = client.RunCommand(cmdTestPort).Result; - if (String.IsNullOrEmpty(cmdResult) == false) - { - string[] cmdResultArry80 = cmdResult.Split(' '); - client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); - client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); - client.RunCommand($"kill -9 {cmdResultArry80[3]}"); - } - MessageBox.Show("释放完毕!"); - client.Disconnect(); - } - } - catch(Exception ex) - { - MessageBox.Show(ex.Message); - } - } - - //private void ButtonGuideConfiguration_Click(object sender, RoutedEventArgs e) - //{ - // MessageBox.Show("尚未完善,敬请期待"); - //} - - //private void ButtonAdvancedConfiguration_Click(object sender, RoutedEventArgs e) - //{ - // MessageBox.Show("尚未完善,敬请期待"); - //} - - #region 资源工具标签页控制 - private void ButtonWebBrowserBack_Click(object sender, RoutedEventArgs e) - { - try - { - WebBrowserResourcesAndTools.GoBack(); - } - catch(Exception ex) - { - MessageBox.Show(ex.Message); - } - } - - private void ButtonWebBrowserForward_Click(object sender, RoutedEventArgs e) - { - try - { - WebBrowserResourcesAndTools.GoForward(); - } - catch (Exception ex) - { - MessageBox.Show(ex.Message); - } - } - - private void ButtonWebBrowserHomePage_Click(object sender, RoutedEventArgs e) - { - try - { - WebBrowserResourcesAndTools.Source=new Uri("https://github.com/proxysu/windows/wiki/ResourcesAndTools"); - } - catch (Exception ex) - { - MessageBox.Show(ex.Message); - } - } #endregion + #region Trojan相关 + //打开Trojan参数设置界面 private void ButtonTrojanTemplate_Click(object sender, RoutedEventArgs e) { @@ -1618,6 +1371,7 @@ namespace ProxySU TrojanTemplateWindow windowTrojanTemplateConfiguration = new TrojanTemplateWindow(); windowTrojanTemplateConfiguration.ShowDialog(); } + //Trojan参数传递 private void ButtonTrojanSetUp_Click(object sender, RoutedEventArgs e) { @@ -1648,6 +1402,7 @@ namespace ProxySU thread.SetApartmentState(ApartmentState.STA); thread.Start(); } + //登录远程主机布署Trojan程序 private void StartSetUpTrojan(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar, string serverConfig, string clientConfig, string upLoadPath) { @@ -2224,6 +1979,7 @@ namespace ProxySU #endregion } + //检测升级远程主机Trojan版本 private void ButtonUpdateTrojan_Click(object sender, RoutedEventArgs e) { @@ -2238,6 +1994,7 @@ namespace ProxySU thread.SetApartmentState(ApartmentState.STA); thread.Start(); } + //升级Trojan主程序 private void UpdateTojan(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) { @@ -2416,7 +2173,9 @@ namespace ProxySU #endregion } + #endregion + #region Trojan-go相关 //打开设置TrojanGo参数窗口 private void ButtonTrojanGoTemplate_Click(object sender, RoutedEventArgs e) @@ -2429,6 +2188,7 @@ namespace ProxySU TrojanGoTemplateWindow windowTrojanGoTemplateConfiguration = new TrojanGoTemplateWindow(); windowTrojanGoTemplateConfiguration.ShowDialog(); } + //传递TrojanGo参数 private void ButtonTrojanGoSetUp_Click(object sender, RoutedEventArgs e) { @@ -2458,6 +2218,7 @@ namespace ProxySU thread.SetApartmentState(ApartmentState.STA); thread.Start(); } + //登录远程主机布署Trojan-Go程序 private void StartSetUpTrojanGo(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar, string serverConfig, string clientConfig, string upLoadPath) { @@ -3016,6 +2777,7 @@ namespace ProxySU #endregion } + //检测升级Trojan-Go版本 private void ButtonUpdateTrojanGo_Click(object sender, RoutedEventArgs e) { @@ -3030,6 +2792,7 @@ namespace ProxySU thread.SetApartmentState(ApartmentState.STA); thread.Start(); } + //升级Trojan-go主程序 private void UpdateTojanGo(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) { @@ -3209,38 +2972,10 @@ namespace ProxySU #endregion } + #endregion + + #region NaiveProxy相关 - //更新NaiveProxy的密码 - private void ButtonNaivePassword_Click(object sender, RoutedEventArgs e) - { - Guid uuid = Guid.NewGuid(); - TextBoxNaivePassword.Text = uuid.ToString(); - } - //生成随机UUID - private string RandomUUID() - { - Guid uuid = Guid.NewGuid(); - //TextBoxNaivePassword.Text = uuid.ToString(); - return uuid.ToString(); - } - //NaiveProxy产生随机用户名 - private string RandomUserName() - { - Random random = new Random(); - int randomSerialNum = random.Next(0, 4); - Guid uuid = Guid.NewGuid(); - string[] pathArray = uuid.ToString().Split('-'); - string path = pathArray[randomSerialNum]; - return path; - // TextBoxPath.Text = $"/{path}"; - //MessageBox.Show(path); - } - //NaiveProxy更改用户名,随机方式 - private void ButtonNaiveUser_Click(object sender, RoutedEventArgs e) - { - TextBoxNaiveUser.Text = RandomUserName(); - } - //NaiveProxy一键安装开始传递参数 private void ButtonNavieSetUp_Click(object sender, RoutedEventArgs e) { @@ -3249,7 +2984,7 @@ namespace ProxySU MessageBox.Show("域名不能为空!"); return; } - + ConnectionInfo connectionInfo = GenerateConnectionInfo(); if (connectionInfo == null) { @@ -3284,12 +3019,15 @@ namespace ProxySU thread.SetApartmentState(ApartmentState.STA); thread.Start(); } + //登录远程主机布署NaiveProxy程序 private void StartSetUpNaive(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar, string serverConfig, string clientConfig, string upLoadPath) { string currentStatus = "正在登录远程主机......"; - Action updateAction = new Action(UpdateTextBlock); + //Action updateAction = new Action(UpdateTextBlock); textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 try { @@ -3326,24 +3064,48 @@ namespace ProxySU client.Connect(); if (client.IsConnected == true) { - currentStatus = "主机登录成功"; + currentStatus = "主机登录成功!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 + Thread.Sleep(1000); } //检测是否运行在root权限下 - string testRootAuthority = client.RunCommand(@"id -u").Result; + currentShellCommandResult = "检测是否运行在root权限下..."; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"id -u"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + string testRootAuthority = currentShellCommandResult; if (testRootAuthority.Equals("0\n") == false) { MessageBox.Show("请使用具有root权限的账户登录主机!!"); client.Disconnect(); return; } + else + { + currentShellCommandResult = "检测结果:OK!"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } //检测是否安装有NaiveProxy currentStatus = "检测系统是否已经安装Caddy......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); - string resultCmdTestTrojanInstalled = client.RunCommand(@"find / -name caddy").Result; + sshShellCommand = @"find / -name caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + string resultCmdTestTrojanInstalled = currentShellCommandResult; if (resultCmdTestTrojanInstalled.Contains("/usr/bin/caddy") == true) { MessageBoxResult messageBoxResult = MessageBox.Show("远程主机已安装Caddy,但不确定是否支持forward proxy,是否强制重新安装?", "", MessageBoxButton.YesNo, MessageBoxImage.Question); @@ -3351,41 +3113,104 @@ namespace ProxySU { currentStatus = "安装取消,退出"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); client.Disconnect(); return; } else { - currentStatus = "正在卸载Caddy"; + currentStatus = "请先行卸载Caddy或重装VPS系统!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); //卸载Caddy代码 } } + else + { + currentShellCommandResult = "检测结果:未安装Caddy!"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } + + //MessageBoxResult messageBoxResult1 = MessageBox.Show("远程主机已安装Caddy,但不确定是否支持forward proxy,是否强制重新安装?", "", MessageBoxButton.YesNo, MessageBoxImage.Question); + //if (messageBoxResult1 == MessageBoxResult.No) + //{ + // currentStatus = "安装取消,退出"; + // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + // Thread.Sleep(1000); + // client.Disconnect(); + // return; + //} //检测远程主机系统环境是否符合要求 currentStatus = "检测系统是否符合安装要求......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); - string resultCmd = client.RunCommand("uname -m").Result; + sshShellCommand = @"uname -m"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + string resultCmd = currentShellCommandResult; + if (resultCmd.Contains("x86_64") == false) { MessageBox.Show($"请在x86_64系统中安装NaiveProxy"); currentStatus = "系统不符合要求,安装失败!!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); } //检测系统是否支持dnf\yum 或 apt或zypper,且支持Systemd //如果不存在组件,则命令结果为空,string.IsNullOrEmpty值为真, - bool getApt = String.IsNullOrEmpty(client.RunCommand("command -v apt").Result); - bool getDnf = String.IsNullOrEmpty(client.RunCommand("command -v dnf").Result); - bool getYum = String.IsNullOrEmpty(client.RunCommand("command -v yum").Result); - bool getZypper = String.IsNullOrEmpty(client.RunCommand("command -v zypper").Result); - bool getSystemd = String.IsNullOrEmpty(client.RunCommand("command -v systemctl").Result); - bool getGetenforce = String.IsNullOrEmpty(client.RunCommand("command -v getenforce").Result); + sshShellCommand = @"command -v apt"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + bool getApt = String.IsNullOrEmpty(currentShellCommandResult); + + sshShellCommand = @"command -v dnf"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + bool getDnf = String.IsNullOrEmpty(currentShellCommandResult); + + sshShellCommand = @"command -v yum"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + bool getYum = String.IsNullOrEmpty(currentShellCommandResult); + + sshShellCommand = @"command -v zypper"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + bool getZypper = String.IsNullOrEmpty(currentShellCommandResult); + + sshShellCommand = @"command -v systemctl"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + bool getSystemd = String.IsNullOrEmpty(currentShellCommandResult); + + sshShellCommand = @"command -v getenforce"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + bool getGetenforce = String.IsNullOrEmpty(currentShellCommandResult); //没有安装apt,也没有安装dnf\yum,也没有安装zypper,或者没有安装systemd的,不满足安装条件 //也就是apt,dnf\yum, zypper必须安装其中之一,且必须安装Systemd的系统才能安装。 @@ -3394,61 +3219,163 @@ namespace ProxySU MessageBox.Show($"系统缺乏必要的安装组件如:apt-get||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本"); currentStatus = "系统环境不满足要求,安装失败!!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); client.Disconnect(); return; } + else + { + currentStatus = "检测结果:OK!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 + if (getGetenforce == false) { - string testSELinux = client.RunCommand("getenforce").Result; + sshShellCommand = @"getenforce"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + string testSELinux = currentShellCommandResult; if (testSELinux.Contains("Enforcing") == true) { - client.RunCommand("setenforce 0");//不重启改为Permissive模式 - client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 + currentStatus = "检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中..."; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + //client.RunCommand("setenforce 0");//不重启改为Permissive模式 + //client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 + sshShellCommand = @"setenforce 0"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = @"sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + currentStatus = "修改完毕!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } } //安装所需软件 + currentStatus = "正在安装依赖的软件......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + if (getApt == false) { - client.RunCommand("apt -qq update"); - client.RunCommand("apt -y -qq install curl libnss3 xz-utils lsof unzip"); + //client.RunCommand("apt -qq update"); + //client.RunCommand("apt -y -qq install curl libnss3 xz-utils lsof unzip"); + sshShellCommand = @"apt -qq update"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"apt -y -qq install curl libnss3 xz-utils lsof unzip"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } - if (getDnf == false) + else if (getDnf == false) { - client.RunCommand("dnf -q makecache"); - client.RunCommand("dnf -y -q install curl nss xz lsof unzip"); + //client.RunCommand("dnf -q makecache"); + //client.RunCommand("dnf -y -q install curl nss xz lsof unzip"); + sshShellCommand = @"dnf -q makecache"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"dnf -y -q install curl nss xz lsof unzip"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } - if (getYum == false) + else if (getYum == false) { - client.RunCommand("yum -q makecache"); - client.RunCommand("yum -y -q install curl nss xz lsof unzip"); + //client.RunCommand("yum -q makecache"); + //client.RunCommand("yum -y -q install curl nss xz lsof unzip"); + sshShellCommand = @"yum -q makecache"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"yum -y -q install curl nss xz lsof unzip"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } - if (getZypper == false) + else if (getZypper == false) { - client.RunCommand("zypper ref"); - client.RunCommand("zypper -y install curl nss xz lsof unzip"); + //client.RunCommand("zypper ref"); + //client.RunCommand("zypper -y install curl nss xz lsof unzip"); + sshShellCommand = @"zypper ref"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"zypper -y install curl nss xz lsof unzip"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } + currentStatus = "安装完毕!OK!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentStatus = "正在检测域名是否解析到当前VPS的IP上......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); + sshShellCommand = @"curl -4 ip.sb"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + string nativeIp = currentShellCommandResult; - string nativeIp = client.RunCommand("curl -4 ip.sb").Result.ToString(); - string testDomainCmd = "ping " + ReceiveConfigurationParameters[4] + " -c 1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; - string resultTestDomainCmd = client.RunCommand(testDomainCmd).Result.ToString(); + sshShellCommand = "ping " + ReceiveConfigurationParameters[4] + " -c 1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + string resultTestDomainCmd = currentShellCommandResult; if (String.Equals(nativeIp, resultTestDomainCmd) == true) { currentStatus = "解析正确!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 Thread.Sleep(1000); } else { currentStatus = "域名未能正确解析到当前VPS的IP上!安装失败!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); MessageBox.Show("域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!"); client.Disconnect(); @@ -3457,15 +3384,33 @@ namespace ProxySU currentStatus = "正在检测端口占用情况......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); - if (String.IsNullOrEmpty(client.RunCommand(@"lsof -n -P -i :80 | grep LISTEN").Result) == false || String.IsNullOrEmpty(client.RunCommand(@"lsof -n -P -i :443 | grep LISTEN").Result) == false) + sshShellCommand = @"lsof -n -P -i :80 | grep LISTEN"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + string testPort80 = currentShellCommandResult; + + sshShellCommand = @"lsof -n -P -i :443 | grep LISTEN"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + string testPort443 = currentShellCommandResult; + + if (String.IsNullOrEmpty(testPort80) == false || String.IsNullOrEmpty(testPort443) == false) { MessageBoxResult dialogResult = MessageBox.Show("80/443端口之一,或全部被占用,将强制停止占用80/443端口的程序?", "Stop application", MessageBoxButton.YesNo); if (dialogResult == MessageBoxResult.No) { currentStatus = "端口被占用,安装失败......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); client.Disconnect(); return; @@ -3473,102 +3418,232 @@ namespace ProxySU currentStatus = "正在释放80/443端口......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); - string cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; - string cmdResult = client.RunCommand(cmdTestPort).Result; - if (String.IsNullOrEmpty(cmdResult) == false) + if (String.IsNullOrEmpty(testPort443) == false) { - string[] cmdResultArry443 = cmdResult.Split(' '); - client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); - client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); - client.RunCommand($"kill -9 {cmdResultArry443[3]}"); + string[] cmdResultArry443 = testPort443.Split(' '); + //client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); + //client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); + //client.RunCommand($"kill -9 {cmdResultArry443[3]}"); + sshShellCommand = $"systemctl stop {cmdResultArry443[0]}"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = $"systemctl disable {cmdResultArry443[0]}"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = $"kill -9 {cmdResultArry443[3]}"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } - cmdTestPort = @"lsof -n -P -i :80 | grep LISTEN"; - cmdResult = client.RunCommand(cmdTestPort).Result; - if (String.IsNullOrEmpty(cmdResult) == false) + if (String.IsNullOrEmpty(testPort80) == false) { - string[] cmdResultArry80 = cmdResult.Split(' '); - client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); - client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); - client.RunCommand($"kill -9 {cmdResultArry80[3]}"); + string[] cmdResultArry80 = testPort80.Split(' '); + //client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); + //client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); + //client.RunCommand($"kill -9 {cmdResultArry80[3]}"); + sshShellCommand = $"systemctl stop {cmdResultArry80[0]}"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = $"systemctl disable {cmdResultArry80[0]}"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = $"kill -9 {cmdResultArry80[3]}"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } currentStatus = "80/443端口释放完毕!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); } + else + { + currentStatus = "检测结果:未被占用!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - currentStatus = "符合安装要求,布署中......"; + } + + currentStatus = "系统环境检测完毕,符合安装要求,开始布署......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); //打开防火墙端口 - string openFireWallPort = "443";//ReceiveConfigurationParameters[1]; + currentStatus = "开启防火墙相应端口......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + //string openFireWallPort = "443";//ReceiveConfigurationParameters[1]; if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) { - if (String.Equals(openFireWallPort, "443")) - { - client.RunCommand("firewall-cmd --zone=public --add-port=80/tcp --permanent"); - client.RunCommand("firewall-cmd --zone=public --add-port=443/tcp --permanent"); - client.RunCommand("firewall-cmd --reload"); - } - else - { - client.RunCommand($"firewall-cmd --zone=public --add-port={openFireWallPort}/tcp --permanent"); - client.RunCommand($"firewall-cmd --zone=public --add-port={openFireWallPort}/udp --permanent"); - client.RunCommand("firewall-cmd --reload"); - } + + //client.RunCommand("firewall-cmd --zone=public --add-port=80/tcp --permanent"); + //client.RunCommand("firewall-cmd --zone=public --add-port=443/tcp --permanent"); + //client.RunCommand("firewall-cmd --reload"); + sshShellCommand = @"firewall-cmd --zone=public --add-port=80/tcp --permanent"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"firewall-cmd --zone=public --add-port=443/tcp --permanent"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"yes | firewall-cmd --reload"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } if (String.IsNullOrEmpty(client.RunCommand("command -v ufw").Result) == false) { - if (String.Equals(openFireWallPort, "443")) - { - client.RunCommand("ufw allow 80"); - client.RunCommand("ufw allow 443"); - client.RunCommand("yes | ufw reload"); - } - else - { - client.RunCommand($"ufw allow {openFireWallPort}/tcp"); - client.RunCommand($"ufw allow {openFireWallPort}/udp"); - client.RunCommand("yes | ufw reload"); - } + //client.RunCommand("ufw allow 80"); + //client.RunCommand("ufw allow 443"); + //client.RunCommand("yes | ufw reload"); + + sshShellCommand = @"ufw allow 80"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"ufw allow 443"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"yes | ufw reload"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } - currentStatus = "正在安装Caddy"; + currentStatus = "正在安装Caddy......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); //安装Caddy //为假则表示系统有相应的组件。 if (getApt == false) { - client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); - client.RunCommand("apt install -y apt-transport-https"); - client.RunCommand("apt -qq update"); - client.RunCommand("apt -y -qq install caddy"); + //client.RunCommand(@"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"); + //client.RunCommand("apt install -y apt-transport-https"); + //client.RunCommand("apt -qq update"); + //client.RunCommand("apt -y -qq install caddy"); + sshShellCommand = @"echo ""deb [trusted=yes] https://apt.fury.io/caddy/ /"" | tee -a /etc/apt/sources.list.d/caddy-fury.list"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"apt install -y apt-transport-https"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"apt -qq update"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"apt -y -qq install caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } else if (getDnf == false) { - client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); - client.RunCommand(@"dnf copr enable @caddy/caddy -y"); - //client.RunCommand("dnf -q makecache"); - client.RunCommand("dnf -y -q install caddy"); + //client.RunCommand(@"dnf install 'dnf-command(copr)' -y"); + //client.RunCommand(@"dnf copr enable @caddy/caddy -y"); + ////client.RunCommand("dnf -q makecache"); + //client.RunCommand("dnf -y -q install caddy"); + sshShellCommand = @"dnf install 'dnf-command(copr)' -y"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"dnf copr enable @caddy/caddy -y"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + //sshShellCommand = @"dnf -q makecache"; + //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + //currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"dnf -y -q install caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } else if (getYum == false) { - client.RunCommand(@"yum install yum-plugin-copr -y"); - client.RunCommand(@"yum copr enable @caddy/caddy -y"); - //client.RunCommand("yum -q makecache"); - client.RunCommand("yum -y -q install caddy"); + //client.RunCommand(@"yum install yum-plugin-copr -y"); + //client.RunCommand(@"yum copr enable @caddy/caddy -y"); + ////client.RunCommand("yum -q makecache"); + //client.RunCommand("yum -y -q install caddy"); + sshShellCommand = @"yum install yum-plugin-copr -y"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"yum copr enable @caddy/caddy -y"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + //sshShellCommand = @"yum -q makecache"; + //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + //currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"yum -y -q install caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } //else if (getZypper == false) //{ // client.RunCommand("zypper ref"); // client.RunCommand("zypper -y install curl"); //} - string installResult = client.RunCommand("find / -name caddy").Result.ToString(); + sshShellCommand = @"find / -name caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + string installResult = currentShellCommandResult; if (!installResult.Contains("/usr/bin/caddy")) { @@ -3576,6 +3651,9 @@ namespace ProxySU currentStatus = "安装Caddy失败!退出"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + client.Disconnect(); return; } @@ -3583,28 +3661,71 @@ namespace ProxySU { currentStatus = "Caddy安装成功!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); - client.RunCommand("systemctl enable caddy"); + //client.RunCommand("systemctl enable caddy"); + sshShellCommand = @"systemctl enable caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } //使用带插件的Caddy替换 currentStatus = "正在为NaiveProxy升级服务端!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); - client.RunCommand(@"curl -o /tmp/caddy.zip https://raw.githubusercontent.com/proxysu/Resources/master/Caddy2/caddy20200816.zip"); - client.RunCommand(@"unzip /tmp/caddy.zip"); //解压到当前目录 ~/ - client.RunCommand(@"chmod +x caddy"); - client.RunCommand(@"systemctl stop caddy;rm -f /usr/bin/caddy"); - client.RunCommand(@"cp ./caddy /usr/bin/"); + //client.RunCommand(@"curl -o /tmp/caddy.zip https://raw.githubusercontent.com/proxysu/Resources/master/Caddy2/caddy20200816.zip"); + //client.RunCommand(@"unzip /tmp/caddy.zip"); //解压到当前目录 ~/ + //client.RunCommand(@"chmod +x caddy"); + //client.RunCommand(@"systemctl stop caddy;rm -f /usr/bin/caddy"); + //client.RunCommand(@"cp ./caddy /usr/bin/"); + sshShellCommand = @"curl -o /tmp/caddy.zip https://raw.githubusercontent.com/proxysu/Resources/master/Caddy2/caddy20200816.zip"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"unzip /tmp/caddy.zip"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"chmod +x ./caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"systemctl stop caddy;rm -f /usr/bin/caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"cp ./caddy /usr/bin/"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + currentStatus = "升级完毕,OK!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 currentStatus = "上传Caddy配置文件......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); //生成服务端配置 - + //string email = $"user@{ReceiveConfigurationParameters[4]}";//生成Caddyfile文件中的tls 邮箱 string caddyConfig = "TemplateConfg\\Naiveproxy_server_config.json"; using (StreamReader reader = File.OpenText(caddyConfig)) @@ -3630,9 +3751,47 @@ namespace ProxySU File.Delete(@"config.json"); - client.RunCommand(@"sed -i 's/Caddyfile/config.json/' /lib/systemd/system/caddy.service"); - client.RunCommand("systemctl daemon-reload"); - client.RunCommand("systemctl restart caddy"); //启动Caddy服务 + currentStatus = "Caddy配置文件上传成功......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + + currentStatus = "设置Caddy自启配置文件......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + //client.RunCommand(@"sed -i 's/Caddyfile/config.json/' /lib/systemd/system/caddy.service"); + //client.RunCommand("systemctl daemon-reload"); + //client.RunCommand("systemctl restart caddy"); //启动Caddy服务 + sshShellCommand = @"sed -i 's/Caddyfile/config.json/' /lib/systemd/system/caddy.service"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"systemctl daemon-reload"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + currentStatus = "设置完毕,正在重启Caddy......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + + sshShellCommand = @"systemctl restart caddy"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + currentStatus = "重启Caddy完毕,OK!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + ////设置伪装网站 //if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) //{ @@ -3644,69 +3803,209 @@ namespace ProxySU currentStatus = "正在优化网络参数......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); //优化网络参数 - string sshCmd = @"bash -c 'echo ""fs.file-max = 51200"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.core.rmem_max = 67108864"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.core.wmem_max = 67108864"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.core.rmem_default = 65536"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.core.wmem_default = 65536"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.core.netdev_max_backlog = 4096"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.core.somaxconn = 4096"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_syncookies = 1"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_tw_reuse = 1"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_tw_recycle = 0"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_fin_timeout = 30"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_keepalive_time = 1200"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.ip_local_port_range = 10000 65000"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_max_syn_backlog = 4096"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_max_tw_buckets = 5000"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_rmem = 4096 87380 67108864"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_wmem = 4096 65536 67108864"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"bash -c 'echo ""net.ipv4.tcp_mtu_probing = 1"" >> /etc/sysctl.conf'"; - client.RunCommand(sshCmd); - sshCmd = @"sysctl -p"; - client.RunCommand(sshCmd); + sshShellCommand = @"bash -c 'echo ""fs.file-max = 51200"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.core.rmem_max = 67108864"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.core.wmem_max = 67108864"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.core.rmem_default = 65536"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.core.wmem_default = 65536"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.core.netdev_max_backlog = 4096"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.core.somaxconn = 4096"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_syncookies = 1"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_tw_reuse = 1"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_tw_recycle = 0"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_fin_timeout = 30"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_keepalive_time = 1200"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.ip_local_port_range = 10000 65000"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_max_syn_backlog = 4096"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_max_tw_buckets = 5000"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_rmem = 4096 87380 67108864"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_wmem = 4096 65536 67108864"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_mtu_probing = 1"" >> /etc/sysctl.conf'"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"sysctl -p"; + //client.RunCommand(sshShellCommand); + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentStatus = "优化网络参数,OK!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); //测试BBR条件,若满足提示是否启用 - var result = client.RunCommand("uname -r"); - string[] linuxKernelVerStr = result.Result.Split('-'); + currentStatus = "BBR测试......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + + //var result = client.RunCommand("uname -r"); + sshShellCommand = @"uname -r"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + string[] linuxKernelVerStr = currentShellCommandResult.Split('-'); bool detectResult = DetectKernelVersionBBR(linuxKernelVerStr[0]); - string resultCmdTestBBR = client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; + //client.RunCommand(@"sysctl net.ipv4.tcp_congestion_control | grep bbr").Result; + sshShellCommand = @"sysctl net.ipv4.tcp_congestion_control | grep bbr"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + string resultCmdTestBBR = currentShellCommandResult; //如果内核满足大于等于4.9,且还未启用BBR,则启用BBR if (detectResult == true && resultCmdTestBBR.Contains("bbr") == false) { - client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); - client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); - client.RunCommand(@"sysctl -p"); + currentStatus = "正在启用BBR......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + Thread.Sleep(1000); + + //client.RunCommand(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); + //client.RunCommand(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); + //client.RunCommand(@"sysctl -p"); + sshShellCommand = @"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + sshShellCommand = @"sysctl -p"; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 + currentShellCommandResult = client.RunCommand(sshShellCommand).Result; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } + else if(resultCmdTestBBR.Contains("bbr") == true) + { + currentStatus = "BBR已经启用了!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + } + else + { + currentStatus = "系统不满足启用BBR的条件,启用失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + } - //生成客户端配置 - currentStatus = "生成客户端配置......"; + //生成客户端配置 + currentStatus = "生成客户端配置......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); if (!Directory.Exists("naive_config"))//如果不存在就创建file文件夹      { @@ -3725,8 +4024,11 @@ namespace ProxySU } client.Disconnect(); - currentStatus = "安装成功"; + currentStatus = "NaiveProxy安装成功!祝您使用愉快!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + Thread.Sleep(1000); //显示服务端连接参数 @@ -3768,12 +4070,255 @@ namespace ProxySU } currentStatus = "主机登录失败"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 } #endregion } + + //更新NaiveProxy的密码 + private void ButtonNaivePassword_Click(object sender, RoutedEventArgs e) + { + Guid uuid = Guid.NewGuid(); + TextBoxNaivePassword.Text = uuid.ToString(); + } + //生成随机UUID + private string RandomUUID() + { + Guid uuid = Guid.NewGuid(); + //TextBoxNaivePassword.Text = uuid.ToString(); + return uuid.ToString(); + } + + //NaiveProxy产生随机用户名 + private string RandomUserName() + { + Random random = new Random(); + int randomSerialNum = random.Next(0, 4); + Guid uuid = Guid.NewGuid(); + string[] pathArray = uuid.ToString().Split('-'); + string path = pathArray[randomSerialNum]; + return path; + // TextBoxPath.Text = $"/{path}"; + //MessageBox.Show(path); + } + + //NaiveProxy更改用户名,随机方式 + private void ButtonNaiveUser_Click(object sender, RoutedEventArgs e) + { + TextBoxNaiveUser.Text = RandomUserName(); + } + +#endregion + + #region 其他功能函数及系统工具相关 + //上传配置文件 + private void UploadConfig(ConnectionInfo connectionInfo, string uploadConfig, string upLoadPath) + { + try + { + using (var sftpClient = new SftpClient(connectionInfo)) + { + sftpClient.Connect(); + //MessageBox.Show("sftp信息1" + sftpClient.ConnectionInfo.ServerVersion.ToString()); + //sftpClient.UploadFile(File.OpenRead("TemplateConfg\tcp_server_config.json"), "/etc/v2ray/config.json", true); + FileStream openUploadConfigFile = File.OpenRead(uploadConfig); + sftpClient.UploadFile(openUploadConfigFile, upLoadPath, true); + openUploadConfigFile.Close(); + //MessageBox.Show("sftp信息" + sftpClient.ConnectionInfo.ServerVersion.ToString()); + sftpClient.Disconnect(); + } + + } + catch (Exception ex2) + { + MessageBox.Show("sftp" + ex2.ToString()); + MessageBox.Show("sftp出现未知错误,上传文件失败,请重试!"); + return; + } + } + + //下载配置文件 + private void DownloadConfig(ConnectionInfo connectionInfo, string downloadConfig, string downloadPath) + { + try + { + using (var sftpClient = new SftpClient(connectionInfo)) + { + sftpClient.Connect(); + //MessageBox.Show("sftp信息1" + sftpClient.ConnectionInfo.ServerVersion.ToString()); + FileStream createDownloadConfig = File.Open(downloadConfig, FileMode.Create); + sftpClient.DownloadFile(downloadPath, createDownloadConfig); + createDownloadConfig.Close(); + //MessageBox.Show("sftp信息" + sftpClient.ConnectionInfo.ServerVersion.ToString()); + sftpClient.Disconnect(); + } + + } + catch (Exception ex2) + { + MessageBox.Show("sftp" + ex2.ToString()); + MessageBox.Show("sftp出现未知错误,下载文件失败,请重试!"); + return; + } + } + + //更新UI显示内容 + Action updateAction = new Action(UpdateTextBlock); + private static void UpdateTextBlock(TextBlock textBlockName, ProgressBar progressBar, string currentStatus) + { + textBlockName.Text = currentStatus; + + if (currentStatus.Contains("成功") == true) + { + progressBar.IsIndeterminate = false; + progressBar.Value = 100; + } + else if (currentStatus.Contains("失败") == true || currentStatus.Contains("取消") == true || currentStatus.Contains("退出") == true) + { + progressBar.IsIndeterminate = false; + progressBar.Value = 0; + } + else + { + progressBar.IsIndeterminate = true; + //progressBar.Value = 0; + } + + + } + + //更新监视窗内的显示内容 + Action updateMonitorAction = new Action(UpdateTextBox); + private static void UpdateTextBox(TextBox textBoxName, string currentResult) + { + textBoxName.Text = textBoxName.Text + currentResult + Environment.NewLine; + textBoxName.ScrollToEnd(); + } + + //检测系统内核是否符合安装要求 + private static bool DetectKernelVersion(string kernelVer) + { + string[] linuxKernelCompared = kernelVer.Split('.'); + if (int.Parse(linuxKernelCompared[0]) > 2) + { + //MessageBox.Show($"当前系统内核版本为{result.Result},符合安装要求!"); + return true; + } + else if (int.Parse(linuxKernelCompared[0]) < 2) + { + //MessageBox.Show($"当前系统内核版本为{result.Result},V2ray要求内核为2.6.23及以上。请升级内核再安装!"); + return false; + } + else if (int.Parse(linuxKernelCompared[0]) == 2) + { + if (int.Parse(linuxKernelCompared[1]) > 6) + { + //MessageBox.Show($"当前系统内核版本为{result.Result},符合安装要求!"); + return true; + } + else if (int.Parse(linuxKernelCompared[1]) < 6) + { + //MessageBox.Show($"当前系统内核版本为{result.Result},V2ray要求内核为2.6.23及以上。请升级内核再安装!"); + return false; + } + else if (int.Parse(linuxKernelCompared[1]) == 6) + { + if (int.Parse(linuxKernelCompared[2]) < 23) + { + //MessageBox.Show($"当前系统内核版本为{result.Result},V2ray要求内核为2.6.23及以上。请升级内核再安装!"); + return false; + } + else + { + //MessageBox.Show($"当前系统内核版本为{result.Result},符合安装要求!"); + return true; + } + + } + } + return false; + + } + + + //打开系统工具中的校对时间窗口 + private void ButtonProofreadTime_Click(object sender, RoutedEventArgs e) + { + ConnectionInfo connectionInfo = GenerateConnectionInfo(); + if (connectionInfo == null) + { + MessageBox.Show("远程主机连接信息有误,请检查"); + return; + } + + ProofreadTimeWindow proofreadTimeWindow = new ProofreadTimeWindow(); + ProofreadTimeWindow.ProfreadTimeReceiveConnectionInfo = connectionInfo; + + proofreadTimeWindow.ShowDialog(); + + } + //释放80/443端口 + private void ButtonClearOccupiedPorts_Click(object sender, RoutedEventArgs e) + { + MessageBoxResult dialogResult = MessageBox.Show("将强制停止占用80/443端口的程序?", "Stop application", MessageBoxButton.YesNo); + if (dialogResult == MessageBoxResult.No) + { + return; + } + + ConnectionInfo testconnect = GenerateConnectionInfo(); + try + { + using (var client = new SshClient(testconnect)) + { + client.Connect(); + + //检测是否运行在root权限下 + string testRootAuthority = client.RunCommand(@"id -u").Result; + if (testRootAuthority.Equals("0\n") == false) + { + MessageBox.Show("请使用具有root权限的账户登录主机!!"); + client.Disconnect(); + return; + } + string cmdTestPort; + string cmdResult; + cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; + cmdResult = client.RunCommand(cmdTestPort).Result; + //MessageBox.Show(cmdTestPort); + if (String.IsNullOrEmpty(cmdResult) == false) + { + //MessageBox.Show(cmdResult); + string[] cmdResultArry443 = cmdResult.Split(' '); + //MessageBox.Show(cmdResultArry443[3]); + client.RunCommand($"systemctl stop {cmdResultArry443[0]}"); + client.RunCommand($"systemctl disable {cmdResultArry443[0]}"); + client.RunCommand($"kill -9 {cmdResultArry443[3]}"); + } + + cmdTestPort = @"lsof -n -P -i :80 | grep LISTEN"; + cmdResult = client.RunCommand(cmdTestPort).Result; + if (String.IsNullOrEmpty(cmdResult) == false) + { + string[] cmdResultArry80 = cmdResult.Split(' '); + client.RunCommand($"systemctl stop {cmdResultArry80[0]}"); + client.RunCommand($"systemctl disable {cmdResultArry80[0]}"); + client.RunCommand($"kill -9 {cmdResultArry80[3]}"); + } + MessageBox.Show("释放完毕!"); + client.Disconnect(); + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + //启用BBR private void ButtonTestAndEnableBBR_Click(object sender, RoutedEventArgs e) { @@ -3783,7 +4328,7 @@ namespace ProxySU MessageBox.Show("远程主机连接信息有误,请检查"); return; } - + Thread thread = new Thread(() => StartTestAndEnableBBR(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); @@ -3878,7 +4423,7 @@ namespace ProxySU client.Disconnect(); return; } - + currentStatus = "内核符合要求,启用中......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); Thread.Sleep(1000); @@ -3898,7 +4443,7 @@ namespace ProxySU currentStatus = "远程主机已启用BBR!成功!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); Thread.Sleep(1000); - } + } else { MessageBoxResult messageBoxResult = MessageBox.Show("BBR启用失败!原因未知,请重试或更换系统为CentOS8/Debian9/10/Ubuntu18.04及以上"); @@ -3906,7 +4451,7 @@ namespace ProxySU currentStatus = "BBR启用失败!"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); Thread.Sleep(1000); - + } client.Disconnect(); @@ -3970,14 +4515,54 @@ namespace ProxySU } else if (int.Parse(linuxKernelCompared[1]) < 9) { - return false; + return false; } - + } return false; } - + #endregion + + #region 资源工具标签页控制 + private void ButtonWebBrowserBack_Click(object sender, RoutedEventArgs e) + { + try + { + WebBrowserResourcesAndTools.GoBack(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + + private void ButtonWebBrowserForward_Click(object sender, RoutedEventArgs e) + { + try + { + WebBrowserResourcesAndTools.GoForward(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + + private void ButtonWebBrowserHomePage_Click(object sender, RoutedEventArgs e) + { + try + { + WebBrowserResourcesAndTools.Source = new Uri("https://github.com/proxysu/windows/wiki/ResourcesAndTools"); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + #endregion + + #region 三合一安装过程 //生成三合一的v2ray路径 private void ButtonV2rayPath3in1_Click(object sender, RoutedEventArgs e) @@ -3985,26 +4570,31 @@ namespace ProxySU string path = RandomUserName(); TextBoxV2rayPath3in1.Text = $"/{path}"; } + //生成三合一Trojan密码 private void ButtonTrojanPassword3in1_Click(object sender, RoutedEventArgs e) { TextBoxTrojanPassword3in1.Text = RandomUUID(); } + //生成三合一V2ray的UUID private void ButtonV2rayUUID3in1_Click(object sender, RoutedEventArgs e) { TextBoxV2rayUUID3in1.Text = RandomUUID(); } + //生成三合一中Naive的用户名 private void ButtonNaiveUser3in1_Click(object sender, RoutedEventArgs e) { TextBoxNaiveUser3in1.Text = RandomUserName(); } + //生成三合一中Naive的密码 private void ButtonNaivePassword3in1_Click(object sender, RoutedEventArgs e) { TextBoxNaivePassword3in1.Text = RandomUUID(); } + //启用三合一安装运行 private void Button_Login3in1_Click(object sender, RoutedEventArgs e) { @@ -4057,6 +4647,7 @@ namespace ProxySU thread.SetApartmentState(ApartmentState.STA); thread.Start(); } + //登录远程主机布署三合一程序 private void StartSetUp3in1(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar, string serverConfig, string clientConfig, string upLoadPath) { @@ -4952,14 +5543,16 @@ namespace ProxySU #endregion } + #endregion + private void Button_Click(object sender, RoutedEventArgs e) + { + string currentStatus = "正在登录远程主机......"; + + currentShellCommandResult = currentStatus; + TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult); - //private void ButtonTestTrojanClientInfoWin_Click(object sender, RoutedEventArgs e) - //{ - // //TrojanResultClientInfoWindow resultClientInformation = new TrojanResultClientInfoWindow(); - // //resultClientInformation.ShowDialog(); - // MessageBox.Show(ReceiveConfigurationParameters[4]); - //} + } } } diff --git a/ProxySU/bin/Beta/Beta.zip b/ProxySU/bin/Beta/Beta.zip index f7ffbbfb265d04f405e7b446e0d69fdb70b71ba2..d8f324a603458b1eb2d14b71774bcf8bbd69c80e 100644 GIT binary patch delta 49785 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

}4^SJ)E;HX|-=w4R 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 C4oETp