From 249282012d7acd209c21bdb0c2409aded7d30d57 Mon Sep 17 00:00:00 2001 From: ProxySU Date: Wed, 21 Oct 2020 23:08:58 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProxySU/MainWindow.xaml | 2 +- ProxySU/MainWindow.xaml.cs | 5993 +++-------------------- ProxySU/Properties/AssemblyInfo.cs | 4 +- ProxySU/Translations/ProxySU.en-US.xaml | 1 + ProxySU/Translations/ProxySU.zh-CN.xaml | 1 + ProxySU/Translations/ProxySU.zh-TW.xaml | 1 + ProxySU/bin/Beta/Beta.zip | Bin 584064 -> 580295 bytes 7 files changed, 748 insertions(+), 5254 deletions(-) diff --git a/ProxySU/MainWindow.xaml b/ProxySU/MainWindow.xaml index 9c1c4c0..41fe76f 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 - v2.4.5" Height="675" Width="650"> + Title="ProxySU - v2.4.6" Height="675" Width="650"> diff --git a/ProxySU/MainWindow.xaml.cs b/ProxySU/MainWindow.xaml.cs index 99dc0f9..04adc3d 100644 --- a/ProxySU/MainWindow.xaml.cs +++ b/ProxySU/MainWindow.xaml.cs @@ -53,19 +53,23 @@ namespace ProxySU //ReceiveConfigurationParameters[8]----方案名称 //ReceiveConfigurationParameters[9]----插件参数选项/VMESS tcp Path/MTProto Parameters //public static ConnectionInfo ConnectionInfo; - public static string proxyType = "V2Ray"; //代理类型标识: V2Ray\TrojanGo\Trojan\NaiveProxy - static bool testDomain = false; //设置标识--域名是否需要检测解析,初始化为不需要 - static bool functionResult = true; //标示功能函数是否执行状态(true无错误发生/false有错误发生) - static string sshShellCommand; //定义保存执行的命令 - static string currentStatus; //定议保存要显示的状态 - static string currentShellCommandResult; //定义Shell命令执行结果保存变量 - static bool getApt = false; //判断系统软件管理,下同 + public static string proxyType = "V2Ray"; //代理类型标识: V2Ray\TrojanGo\Trojan\NaiveProxy + static bool testDomain = false; //设置标识--域名是否需要检测解析,初始化为不需要 + static string ipv4 = String.Empty; //保存获取的ipv4地址 + static string ipv6 = String.Empty; //保存获取的ipv6地址 + static bool onlyIpv6 = false; //acme.sh申请证书是否基于纯ipv6地址 + static string scriptGithubUrl = "raw.githubusercontent.com";//安装脚本下载地址 + static bool functionResult = true; //标示功能函数是否执行状态(true无错误发生/false有错误发生) + static string sshShellCommand = String.Empty; //定义保存执行的命令 + static string currentStatus = String.Empty; //定议保存要显示的状态 + static string currentShellCommandResult = String.Empty; //定义Shell命令执行结果保存变量 + static bool getApt = false; //判断系统软件管理,下同 static bool getDnf = false; static bool getYum = false; - static string sshCmdUpdate; //保存软件安装所用更新软件库命令 - static string sshCmdInstall; //保存软件安装所用命令格式 - static int randomCaddyListenPort = 8800; //Caddy做伪装网站所监听的端口,随机10001-60000 - static int installationDegree = 0; //安装进度条显示的百分比 + static string sshCmdUpdate = String.Empty; //保存软件安装所用更新软件库命令 + static string sshCmdInstall = String.Empty; //保存软件安装所用命令格式 + static int randomCaddyListenPort = 8800; //Caddy做伪装网站所监听的端口,随机10001-60000 + static int installationDegree = 0; //安装进度条显示的百分比 //****** ****** // Application.Current.FindResource("").ToString() @@ -1035,13 +1039,13 @@ namespace ProxySU } //登录远程主机布署V2ray程序 - private void StartSetUpV2ray(ConnectionInfo connectionInfo) { functionResult = true; getApt = false; getDnf = false; getYum = false; + //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); @@ -1289,7 +1293,7 @@ namespace ProxySU currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + "V2Ray......"; MainWindowsShowInfo(currentStatus); - sshShellCommand = @"curl -o /tmp/go.sh https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh"; + sshShellCommand = $"curl -o /tmp/go.sh https://{scriptGithubUrl}/v2fly/fhs-install-v2ray/master/install-release.sh"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"yes | bash /tmp/go.sh -f"; @@ -2021,20 +2025,24 @@ namespace ProxySU return; } installationDegree = 0; - Thread thread = new Thread(() => UpdateV2ray(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + TextBoxMonitorCommandResults.Text = ""; + Thread thread = new Thread(() => UpdateV2ray(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //升级V2ray主程序 - private void UpdateV2ray(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void UpdateV2ray(ConnectionInfo connectionInfo) { - //******"正在登录远程主机......"******01 + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; + + //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); - string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); + MainWindowsShowInfo(currentStatus); try { @@ -2071,248 +2079,49 @@ namespace ProxySU client.Connect(); if (client.IsConnected == true) { - //******"主机登录成功"******02 - SetUpProgressBarProcessing(5); + //******"主机登录成功"****** + SetUpProgressBarProcessing(3); currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } - //******"检测是否运行在root权限下..."******03 - SetUpProgressBarProcessing(10); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - 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);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - string testRootAuthority = currentShellCommandResult; - if (testRootAuthority.Equals("0\n") == false) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(15); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } //******"检测系统是否已经安装V2ray......"****** SetUpProgressBarProcessing(20); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "V2ray......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); //Thread.Sleep(1000); //检测是否安装V2Ray sshShellCommand = @"find / -name v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - string resultCmdTestV2rayInstalled = currentShellCommandResult; - - if (resultCmdTestV2rayInstalled.Contains("/usr/bin/v2ray") == false && resultCmdTestV2rayInstalled.Contains("/usr/local/bin/v2ray") == false) + if (currentShellCommandResult.Contains("/usr/local/bin/v2ray") == false) { //******"退出!原因:远程主机未安装V2ray"****** MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorUpgradeSoftNotInstall").ToString() + "V2Ray!"); //******"退出!原因:远程主机未安装V2ray"****** currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorUpgradeSoftNotInstall").ToString() + "V2Ray!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); client.Disconnect(); return; } - else if (resultCmdTestV2rayInstalled.Contains("/usr/bin/v2ray") == true) - { - //****** "检测到使用旧安装脚本的V2Ray......" ****** - SetUpProgressBarProcessing(30); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_OldScriptInstalledV2Ray").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //****** "检测到使用旧安装脚本的V2Ray,是否卸载旧版本并使用新安装脚本重新安装?" ****** - MessageBoxResult messageBoxResult = MessageBox.Show(Application.Current.FindResource("MessageBoxShow_OldScriptInstalledV2Ray").ToString(), "", MessageBoxButton.YesNo, MessageBoxImage.Question); - if (messageBoxResult == MessageBoxResult.No) - { - //******"安装取消,退出"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstallationCanceledExit").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //****** "正在卸载旧版本......" ****** - SetUpProgressBarProcessing(40); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_RemoveOldScriptInstalledV2Ray").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - } - - SetUpProgressBarProcessing(50); - sshShellCommand = @"curl -o /tmp/go.sh https://raw.githubusercontent.com/proxysu/shellscript/master/v2ray/go.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"yes | bash /tmp/go.sh --remove"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"rm -f /tmp/go.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - - sshShellCommand = @"find / -name v2ray"; - 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/v2ray")) - { - //****** "卸载旧版本,OK!" ****** - SetUpProgressBarProcessing(60); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_RemoveOldVersionOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - //****** "安装新版本......" ****** - SetUpProgressBarProcessing(70); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstallNewVersion").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"curl -o /tmp/go.sh https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"yes | bash /tmp/go.sh -f"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"rm -f /tmp/go.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - - sshShellCommand = @"find / -name v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - if (!installResult.Contains("/usr/local/bin/v2ray")) - { - //****** "安装V2ray失败,官方脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallV2RayFail").ToString()); - //****** "安装V2ray失败,官方脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallV2RayFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "V2ray安装成功!" ****** - SetUpProgressBarProcessing(80); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_V2RayInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"systemctl enable v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //****** "迁移原配置文件。" ****** - SetUpProgressBarProcessing(90); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_MoveOriginalConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"mv /etc/v2ray/config.json /usr/local/etc/v2ray/"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"systemctl restart v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //****** "已更新到最新版本。" ****** - SetUpProgressBarProcessing(100); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradedNewVersion").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - //string sshcmd; + //sshcmd = @"/usr/local/bin/v2ray -version | head -n 1 | cut -d "" "" -f2"; sshShellCommand = @"/usr/local/bin/v2ray -version | head -n 1 | cut -d "" "" -f2"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string v2rayCurrentVersion = currentShellCommandResult;//不含字母v - //sshcmd = @"curl -H ""Accept: application/json"" -H ""User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0"" -s ""https://api.github.com/repos/v2fly/v2ray-core/releases/latest"" --connect-timeout 10| grep 'tag_name' | cut -d\"" -f4"; sshShellCommand = @"curl -H ""Accept: application/json"" -H ""User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0"" -s ""https://api.github.com/repos/v2fly/v2ray-core/releases/latest"" --connect-timeout 10 | grep 'tag_name' | cut -d\"" -f4"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string v2rayNewVersion = currentShellCommandResult;//包含字母v @@ -2332,23 +2141,16 @@ namespace ProxySU //****** "正在升级到最新版本......" ****** SetUpProgressBarProcessing(60); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartUpgradeNewVersion").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); + + //client.RunCommand(@"bash <(curl -L -s https://{scriptGithubUrl}/v2fly/fhs-install-v2ray/master/install-release.sh)"); + sshShellCommand = $"bash <(curl -L -s https://{scriptGithubUrl}/v2fly/fhs-install-v2ray/master/install-release.sh)"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //Thread.Sleep(1000); - //client.RunCommand(@"bash <(curl -L -s https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)"); - sshShellCommand = @"bash <(curl -L -s https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 SetUpProgressBarProcessing(80); //sshcmd = @"/usr/local/bin/v2ray -version | head -n 1 | cut -d "" "" -f2"; sshShellCommand = @"/usr/local/bin/v2ray -version | head -n 1 | cut -d "" "" -f2"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); v2rayCurrentVersion = currentShellCommandResult;//不含字母v if (v2rayNewVersion.Contains(v2rayCurrentVersion) == true) @@ -2358,11 +2160,7 @@ namespace ProxySU //****** "升级成功!当前已是最新版本!" ****** SetUpProgressBarProcessing(100); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } else { @@ -2370,22 +2168,15 @@ namespace ProxySU MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionFail").ToString()); //****** "升级失败,原因未知,请向开发者提问!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } } else { //****** "升级取消,退出!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeVersionCancel").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); client.Disconnect(); return; } @@ -2399,11 +2190,7 @@ namespace ProxySU //****** "无需升级!退出!" ****** Application.Current.FindResource("DisplayInstallInfo_NotUpgradeVersion").ToString(); MessageBox.Show(currentStatus); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } client.Disconnect(); @@ -2417,10 +2204,7 @@ namespace ProxySU //****** "主机登录失败!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -2539,13 +2323,13 @@ namespace ProxySU } installationDegree = 0; TextBoxMonitorCommandResults.Text = ""; - Thread thread = new Thread(() => StartSetUpTrojanGo(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + Thread thread = new Thread(() => StartSetUpTrojanGo(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //登录远程主机布署Trojan-Go程序 - private void StartSetUpTrojanGo(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void StartSetUpTrojanGo(ConnectionInfo connectionInfo) { functionResult = true; getApt = false; @@ -2671,7 +2455,7 @@ namespace ProxySU sshShellCommand = @"chmod 644 /usr/local/etc/trojan-go/trojan-go.key"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //Caddy安装 61--66 + //Caddy安装与检测安装是否成功 61--66 functionResult = CaddyInstall(client); if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } @@ -2724,8 +2508,6 @@ namespace ProxySU functionResult = DetectBBRandEnable(client); if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - - client.Disconnect();//断开服务器ssh连接 @@ -2770,7 +2552,6 @@ namespace ProxySU MainWindowsShowInfo(currentStatus); //显示服务端连接参数 - proxyType = "TrojanGo"; ResultClientInformation resultClientInformation = new ResultClientInformation(); @@ -2806,7 +2587,7 @@ namespace ProxySU currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + "Trojan-go......"; MainWindowsShowInfo(currentStatus); - sshShellCommand = @"curl -o /tmp/trojan-go.sh https://raw.githubusercontent.com/proxysu/shellscript/master/trojan-go.sh"; + sshShellCommand = $"curl -o /tmp/trojan-go.sh https://{scriptGithubUrl}/proxysu/shellscript/master/trojan-go.sh"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"yes | bash /tmp/trojan-go.sh -f"; @@ -2885,20 +2666,23 @@ namespace ProxySU return; } installationDegree = 0; - Thread thread = new Thread(() => UpdateTojanGo(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + Thread thread = new Thread(() => UpdateTojanGo(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //升级Trojan-go主程序 - private void UpdateTojanGo(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void UpdateTojanGo(ConnectionInfo connectionInfo) { + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; + //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); - string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); + MainWindowsShowInfo(currentStatus); try { @@ -2936,74 +2720,34 @@ namespace ProxySU if (client.IsConnected == true) { //******"主机登录成功"****** - SetUpProgressBarProcessing(5); + SetUpProgressBarProcessing(3); currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } - //******"检测是否运行在root权限下..."****** - SetUpProgressBarProcessing(10); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - 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) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(15); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } //******"检测系统是否已经安装Trojan-go......"****** SetUpProgressBarProcessing(20); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "Trojan-go......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //string cmdTestTrojanInstalled = @"find / -name trojan-go"; sshShellCommand = @"find / -name trojan-go"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - string resultCmdTestTrojanInstalled = currentShellCommandResult; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - if (resultCmdTestTrojanInstalled.Contains("/usr/local/bin/trojan-go") == false) + if (currentShellCommandResult.Contains("/usr/local/bin/trojan-go") == false) { //******"退出!原因:远程主机未安装Trojan-go"****** MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorUpgradeSoftNotInstall").ToString() + "Trojan-go!"); //******"退出!原因:远程主机未安装Trojan-go"****** currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorUpgradeSoftNotInstall").ToString() + "Trojan-go!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); client.Disconnect(); return; @@ -3012,18 +2756,13 @@ namespace ProxySU //获取当前安装的版本 //string sshcmd = @"echo ""$(/usr/local/bin/trojan-go -version)"" | head -n 1 | cut -d "" "" -f2"; sshShellCommand = @"echo ""$(/usr/local/bin/trojan-go -version)"" | head -n 1 | cut -d "" "" -f2"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string trojanCurrentVersion = currentShellCommandResult;//含字母v + //获取最新版本 //sshcmd = @"curl -s https://api.github.com/repos/p4gefau1t/trojan-go/tags | grep 'name' | cut -d\"" -f4 | head -1"; sshShellCommand = @"curl -s https://api.github.com/repos/p4gefau1t/trojan-go/tags | grep 'name' | cut -d\"" -f4 | head -1"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string trojanNewVersion = currentShellCommandResult;//含字母v if (trojanNewVersion.Equals(trojanCurrentVersion) == false) @@ -3042,41 +2781,29 @@ namespace ProxySU //****** "正在升级到最新版本......" ****** SetUpProgressBarProcessing(60); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartUpgradeNewVersion").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //备份配置文件 //sshcmd = @"mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.bak"; //client.RunCommand(sshcmd); //升级Trojan-Go主程序 - //client.RunCommand("curl -o /tmp/trojan-go.sh https://raw.githubusercontent.com/proxysu/shellscript/master/trojan-go.sh"); + //client.RunCommand("curl -o /tmp/trojan-go.sh https://{scriptGithubUrl}/proxysu/shellscript/master/trojan-go.sh"); //client.RunCommand("yes | bash /tmp/trojan-go.sh -f"); - sshShellCommand = @"curl -o /tmp/trojan-go.sh https://raw.githubusercontent.com/proxysu/shellscript/master/trojan-go.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -o /tmp/trojan-go.sh https://{scriptGithubUrl}/proxysu/shellscript/master/trojan-go.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"yes | bash /tmp/trojan-go.sh -f"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/trojan-go.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); SetUpProgressBarProcessing(80); //获取升级后的版本 //sshcmd = @"echo ""$(/usr/local/bin/trojan-go -version)"" | head -n 1 | cut -d "" "" -f2"; sshShellCommand = @"echo ""$(/usr/local/bin/trojan-go -version)"" | head -n 1 | cut -d "" "" -f2"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); trojanCurrentVersion = currentShellCommandResult;//含字母v if (trojanNewVersion.Equals(trojanCurrentVersion) == true) @@ -3092,11 +2819,7 @@ namespace ProxySU //****** "升级成功!当前已是最新版本!" ****** SetUpProgressBarProcessing(100); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } else { @@ -3104,11 +2827,8 @@ namespace ProxySU MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionFail").ToString()); //****** "升级失败,原因未知,请向开发者提问!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); client.Disconnect(); return; } @@ -3118,11 +2838,8 @@ namespace ProxySU { //****** "升级取消,退出!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeVersionCancel").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); client.Disconnect(); return; } @@ -3136,11 +2853,7 @@ namespace ProxySU //****** "无需升级!退出!" ****** Application.Current.FindResource("DisplayInstallInfo_NotUpgradeVersion").ToString(); MessageBox.Show(currentStatus); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } client.Disconnect(); @@ -3154,10 +2867,7 @@ namespace ProxySU //****** "主机登录失败!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -3216,20 +2926,24 @@ namespace ProxySU //启动布署进程 installationDegree = 0; - Thread thread = new Thread(() => StartSetUpTrojan(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + TextBoxMonitorCommandResults.Text = ""; + Thread thread = new Thread(() => StartSetUpTrojan(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //登录远程主机布署Trojan程序 - private void StartSetUpTrojan(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void StartSetUpTrojan(ConnectionInfo connectionInfo) { + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; + //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); try { @@ -3269,115 +2983,26 @@ namespace ProxySU //******"主机登录成功"****** SetUpProgressBarProcessing(3); currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } - //******"检测是否运行在root权限下..."****** - SetUpProgressBarProcessing(5); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"id -u"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测是否已安装代理 8--10 + functionResult = SoftInstalledIsNoYes(client, "trojan", @"/usr/local/bin/trojan"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - string testRootAuthority = currentShellCommandResult; - if (testRootAuthority.Equals("0\n") == false) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(8); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测关闭Selinux及系统组件是否齐全(apt/yum/dnf/systemctl)11--30 + //安装依赖软件,检测端口,防火墙开启端口 + functionResult = ShutDownSelinuxAndSysComponentsDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - } - - //******"检测系统是否已经安装Trojan......"****** - SetUpProgressBarProcessing(10); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "Trojan......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"find / -name trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - string resultCmdTestTrojanInstalled = currentShellCommandResult; - - if (resultCmdTestTrojanInstalled.Contains("/usr/local/bin/trojan") == true) - { - MessageBoxResult messageBoxResult = MessageBox.Show( - //******"远程主机已安装"****** - Application.Current.FindResource("MessageBoxShow_ExistedSoft").ToString() + - "Trojan" + - //******",是否强制重新安装?"****** - Application.Current.FindResource("MessageBoxShow_ForceInstallSoft").ToString(), "", MessageBoxButton.YesNo, MessageBoxImage.Question); - if (messageBoxResult == MessageBoxResult.No) - { - //******"安装取消,退出"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstallationCanceledExit").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //******"已选择强制安装Trojan-go!"****** - SetUpProgressBarProcessing(12); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ForceInstallSoft").ToString() + "Trojan!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - } - } - else - { - //******"检测结果:未安装Trojan!"****** - SetUpProgressBarProcessing(12); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "Trojan!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus);//显示命令执行的结果 - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //******"检测系统是否符合安装要求......"****** - SetUpProgressBarProcessing(14); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_CheckSystemRequirements").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + //检测是否为64位系统 sshShellCommand = @"uname -m"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string resultCmd = currentShellCommandResult; if (resultCmd.Contains("x86_64") == false) { @@ -3385,479 +3010,40 @@ namespace ProxySU MessageBox.Show(Application.Current.FindResource("MessageBoxShow_PleaseInstallSoftAtX64").ToString() + "NaiveProxy......"); //****** "系统环境不满足要求,安装失败!!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_MissingSystemComponents").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - - - //检测系统是否支持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); - - SetUpProgressBarProcessing(16); - - 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的系统才能安装。 - if ((getApt && getDnf && getYum && getZypper) || getSystemd) - { - //******"系统缺乏必要的安装组件如:apt||dnf||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_MissingSystemComponents").ToString()); - - //******"系统环境不满足要求,安装失败!!"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_MissingSystemComponents").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(18); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SystemRequirementsOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //设置安装软件所用的命令格式 - //为假则表示系统有相应的组件。 - - if (getApt == false) - { - sshCmdUpdate = @"apt -qq update"; - sshCmdInstall = @"apt -y -qq install "; - } - else if (getDnf == false) - { - sshCmdUpdate = @"dnf -q makecache"; - sshCmdInstall = @"dnf -y -q install "; - } - else if (getYum == false) - { - sshCmdUpdate = @"yum -q makecache"; - sshCmdInstall = @"yum -y -q install "; - } - else if (getZypper == false) - { - sshCmdUpdate = @"zypper ref"; - sshCmdInstall = @"zypper -y install "; - } - - //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 - if (getGetenforce == false) - { - 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) - { - //******"检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中......"****** - SetUpProgressBarProcessing(20); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableSELinux").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - 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);//显示命令执行的结果 - - //******"修改完毕!"****** - SetUpProgressBarProcessing(22); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SELinuxModifyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - } - - //****** "正在检测域名是否解析到当前VPS的IP上......" ****** - SetUpProgressBarProcessing(28); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestDomainResolve").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //在相应系统内安装curl(如果没有安装curl) - if (string.IsNullOrEmpty(client.RunCommand("command -v curl").Result) == true) - { - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}curl"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //检测域名是否解析正确 - 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; - - 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) - { - //****** "解析正确!OK!" ****** - SetUpProgressBarProcessing(32); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DomainResolveOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "域名未能正确解析到当前VPS的IP上!安装失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorDomainResolve").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //****** "域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorDomainResolve").ToString()); - client.Disconnect(); + MainWindowsShowInfo(currentStatus); return; } - //检测是否安装lsof - if (string.IsNullOrEmpty(client.RunCommand("command -v lsof").Result) == true) - { - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}lsof"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //****** "检测端口占用情况......" ****** - SetUpProgressBarProcessing(34); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestPortUsed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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) - { - //****** "80/443端口之一,或全部被占用,将强制停止占用80/443端口的程序?" ****** - MessageBoxResult dialogResult = MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorPortUsed").ToString(), "Stop application", MessageBoxButton.YesNo); - if (dialogResult == MessageBoxResult.No) - { - //****** "端口被占用,安装失败......" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorPortUsedFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - - //****** "正在释放80/443端口......" ****** - SetUpProgressBarProcessing(37); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ReleasePort").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - if (String.IsNullOrEmpty(testPort443) == false) - { - string[] cmdResultArry443 = testPort443.Split(' '); - - 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);//显示命令执行的结果 - - } - - if (String.IsNullOrEmpty(testPort80) == false) - { - string[] cmdResultArry80 = testPort80.Split(' '); - - 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);//显示命令执行的结果 - - } - //****** "80/443端口释放完毕!" ****** - SetUpProgressBarProcessing(39); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ReleasePortOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "检测结果:未被占用!" ****** - SetUpProgressBarProcessing(41); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_PortNotUsed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - //****** "系统环境检测完毕,符合安装要求,开始布署......" ****** - SetUpProgressBarProcessing(43); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstalling").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //****** "开启防火墙相应端口......" ****** - SetUpProgressBarProcessing(44); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_OpenFireWallPort").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) - { - - 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) - { - 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);//显示命令执行的结果 - - } - - //处理极其少见的xz-utils未安装的情况 - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}xz-utils"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测域名是否解析到当前IP上 34---36 + functionResult = DomainResolutionCurrentIPDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } //下载安装脚本安装 //****** "正在安装Trojan......" ****** - SetUpProgressBarProcessing(46); + SetUpProgressBarProcessing(37); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + "Trojan......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); - - sshShellCommand = @"curl -o /tmp/trojan-quickstart.sh https://raw.githubusercontent.com/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -o /tmp/trojan-quickstart.sh https://{scriptGithubUrl}/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"yes | bash /tmp/trojan-quickstart.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/trojan-quickstart.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - - sshShellCommand = @"find / -name trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - string installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/local/bin/trojan")) - { - //****** "安装失败,官方脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString()); - //****** "安装失败,官方脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "Trojan安装成功!" ****** - SetUpProgressBarProcessing(50); - currentStatus = "Trojan" + Application.Current.FindResource("DisplayInstallInfo_SoftInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"systemctl enable trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - sshShellCommand = @"mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.1"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //程序是否安装成功检测并设置开机启动 41--43 + functionResult = SoftInstalledSuccessOrFail(client, "trojan", @"/usr/local/bin/trojan"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } //****** "安装完毕,上传配置文件......" ****** - SetUpProgressBarProcessing(53); + SetUpProgressBarProcessing(44); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadSoftConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); + sshShellCommand = @"mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.1"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string serverConfig = @"TemplateConfg\trojan\trojan_server_config.json"; //服务端配置文件 string upLoadPath = @"/usr/local/etc/trojan/config.json"; //服务端文件位置 @@ -3885,135 +3071,27 @@ namespace ProxySU File.Delete(@"config.json"); - //****** "正在安装acme.sh......" ****** - SetUpProgressBarProcessing(55); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallAcmeSh").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //安装所依赖的软件 - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}socat"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //解决搬瓦工CentOS缺少问题 - sshShellCommand = $"{sshCmdInstall}automake autoconf libtool"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - - sshShellCommand = @"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("Install success") == true) - { - //****** "acme.sh安装成功!" ****** - SetUpProgressBarProcessing(58); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_AcmeShInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "acme.sh安装失败!原因未知,请向开发者提问!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorAcmeShInstallFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - return; - } - - sshShellCommand = @"cd ~/.acme.sh/"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"alias acme.sh=~/.acme.sh/acme.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - - //****** "申请域名证书......" ****** - SetUpProgressBarProcessing(60); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartApplyCert").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = $"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("Cert success") == true) - { - //****** "证书申请成功!" ****** - SetUpProgressBarProcessing(63); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ApplyCertSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "证书申请失败!原因未知,请向开发者提问!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ApplyCertFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - return; - } + //acme.sh安装与申请证书 51--57 + functionResult = AcmeShInstall(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } //****** "安装证书到Trojan......" ****** - SetUpProgressBarProcessing(65); + SetUpProgressBarProcessing(58); currentStatus = Application.Current.FindResource("DisplayInstallInfo_IntallCertToSoft").ToString() + "Trojan......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); sshShellCommand = $"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/trojan/trojan_ssl.crt --keypath /usr/local/etc/trojan/trojan_ssl.key --capath /usr/local/etc/trojan/trojan_ssl.crt --reloadcmd \"systemctl restart trojan\""; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"if [ ! -f ""/usr/local/etc/trojan/trojan_ssl.key"" ]; then echo ""0""; else echo ""1""; fi | head -n 1"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("1") == true) { //****** "证书成功安装到Trojan!" ****** - SetUpProgressBarProcessing(68); + SetUpProgressBarProcessing(60); currentStatus = Application.Current.FindResource("DisplayInstallInfo_IntallCertToSoftOK").ToString() + "Trojan!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { @@ -4021,148 +3099,25 @@ namespace ProxySU currentStatus = Application.Current.FindResource("DisplayInstallInfo_IntallCertToSoftFail").ToString() + "Trojan" + Application.Current.FindResource("DisplayInstallInfo_InstallCertFailAsk").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); return; } //设置证书权限 sshShellCommand = @"chmod 644 /usr/local/etc/trojan/trojan_ssl.key"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //****** "安装Caddy......" ****** - SetUpProgressBarProcessing(70); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallCaddy").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //安装Caddy - //为假则表示系统有相应的组件。 - if (getApt == false) - { - 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) - { - - 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) - { - 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);//显示命令执行的结果 - - } - - sshShellCommand = @"find / -name caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/bin/caddy")) - { - //****** "安装Caddy失败!" ****** - MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_ErrorInstallCaddyFail").ToString()); - //****** "安装Caddy失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorInstallCaddyFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - - //****** "Caddy安装成功!" ****** - SetUpProgressBarProcessing(75); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstalledCaddyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"systemctl enable caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //Caddy安装 61--66 + functionResult = CaddyInstall(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } //****** "上传Caddy配置文件......" ****** - SetUpProgressBarProcessing(80); + SetUpProgressBarProcessing(67); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadCaddyConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); sshShellCommand = @"mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string caddyConfig = @"TemplateConfg\trojan\trojan.caddyfile"; upLoadPath = @"/etc/caddy/Caddyfile"; @@ -4173,284 +3128,42 @@ namespace ProxySU string randomCaddyListenPortStr = randomCaddyListenPort.ToString(); sshShellCommand = $"sed -i 's/8800/{randomCaddyListenPortStr}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //设置域名 sshShellCommand = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/g' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //设置伪装网站 if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) { sshShellCommand = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); } //****** "Caddy配置文件上传成功,OK!" ****** - SetUpProgressBarProcessing(85); + SetUpProgressBarProcessing(70); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadCaddyConfigOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); + //程序启动检测Caddy + functionResult = SoftStartDetect(client, "caddy", @"/usr/bin/caddy"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //****** "正在启动Caddy......" ****** - SetUpProgressBarProcessing(87); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyService").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //程序启动检测Trojan + functionResult = SoftStartDetect(client, "trojan", @"/usr/local/bin/trojan"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //Thread.Sleep(1000); - //启动Caddy服务 - sshShellCommand = @"systemctl restart caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测BBR,满足条件并启动 90--95 + functionResult = DetectBBRandEnable(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) - { - //****** "Caddy启动成功!" ****** - SetUpProgressBarProcessing(88); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Caddy启动失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - //****** "正在启动Caddy(第二次尝试)!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceSecond").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - sshShellCommand = @"systemctl restart caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) - { - //****** "Caddy启动成功!" ****** - SetUpProgressBarProcessing(88); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Caddy启动失败(第二次)!退出安装!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceSecondFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - //****** "Caddy启动失败,原因未知!请向开发者问询!" ****** - MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_CaddyServiceFailedExit").ToString()); - return; - } - } - - //****** "正在启动Trojan......" ****** - SetUpProgressBarProcessing(90); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartSoft").ToString() + "Trojan......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //启动Trojan服务 - sshShellCommand = @"systemctl restart trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("/usr/local/bin/trojan") == true) - { - //****** "Trojan启动成功!" ****** - SetUpProgressBarProcessing(93); - currentStatus = "Trojan" + Application.Current.FindResource("DisplayInstallInfo_StartSoftOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Trojan启动失败!" ****** - currentStatus = "Trojan" + Application.Current.FindResource("DisplayInstallInfo_StartSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(3000); - - //****** "正在第二次尝试启动Trojan!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartSoftSecond").ToString() + "Trojan!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(3000); - sshShellCommand = @"systemctl restart trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("usr/local/bin/trojan") == true) - { - //****** "Trojan启动成功!" ****** - SetUpProgressBarProcessing(93); - currentStatus = "Trojan" + Application.Current.FindResource("DisplayInstallInfo_StartSoftOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Trojan启动失败(第二次)!退出安装!" ****** - currentStatus = "Trojan" + Application.Current.FindResource("DisplayInstallInfo_StartSoftSecondFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - //****** "Trojan启动失败,原因未知!请向开发者问询!" ****** - MessageBox.Show("Trojan" + Application.Current.FindResource("DisplayInstallInfo_StartSoftFailedExit").ToString()); - return; - } - } - - - //测试BBR条件,若满足则启用 - //****** "BBR测试......" ****** - SetUpProgressBarProcessing(95); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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]); - - 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) - { - //****** "正在启用BBR......" ****** - SetUpProgressBarProcessing(97); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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) - { - //****** "BBR已经启用了!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRisEnabled").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - else - { - //****** "系统不满足启用BBR的条件,启用失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } client.Disconnect();//断开服务器ssh连接 //****** "生成客户端配置......" ****** - SetUpProgressBarProcessing(99); + SetUpProgressBarProcessing(96); currentStatus = Application.Current.FindResource("DisplayInstallInfo_GenerateClientConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); if (!Directory.Exists("trojan_config"))//如果不存在就创建file文件夹      { Directory.CreateDirectory("trojan_config");//创建该文件夹   @@ -4474,11 +3187,7 @@ namespace ProxySU //****** "Trojan安装成功,祝你玩的愉快!!" ****** SetUpProgressBarProcessing(100); currentStatus = "Trojan" + Application.Current.FindResource("DisplayInstallInfo_ProxyInstalledOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //显示服务端连接参数 proxyType = "Trojan"; @@ -4512,20 +3221,24 @@ namespace ProxySU return; } installationDegree = 0; - Thread thread = new Thread(() => UpdateTojan(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + TextBoxMonitorCommandResults.Text = ""; + Thread thread = new Thread(() => UpdateTojan(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //升级Trojan主程序 - private void UpdateTojan(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void UpdateTojan(ConnectionInfo connectionInfo) { + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; + //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); - string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); + MainWindowsShowInfo(currentStatus); try { @@ -4563,73 +3276,35 @@ namespace ProxySU if (client.IsConnected == true) { //******"主机登录成功"****** - SetUpProgressBarProcessing(5); + SetUpProgressBarProcessing(3); currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } - //******"检测是否运行在root权限下..."****** - SetUpProgressBarProcessing(10); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - 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);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - string testRootAuthority = currentShellCommandResult; - if (testRootAuthority.Equals("0\n") == false) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(15); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } //******"检测系统是否已经安装Trojan......"****** SetUpProgressBarProcessing(20); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "Trojan......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); //string cmdTestTrojanInstalled = @"find / -name trojan"; //string resultCmdTestTrojanInstalled = client.RunCommand(cmdTestTrojanInstalled).Result; sshShellCommand = @"find / -name trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - string resultCmdTestTrojanInstalled = currentShellCommandResult; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - if (resultCmdTestTrojanInstalled.Contains("/usr/local/bin/trojan") == false) + if (currentShellCommandResult.Contains("/usr/local/bin/trojan") == false) { //******"退出!原因:远程主机未安装Trojan"****** MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorUpgradeSoftNotInstall").ToString() + "Trojan!"); //******"退出!原因:远程主机未安装Trojan"****** currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorUpgradeSoftNotInstall").ToString() + "Trojan!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); client.Disconnect(); return; @@ -4641,9 +3316,7 @@ namespace ProxySU //string sshcmd = @"echo ""$(/usr/local/bin/trojan -v 2>&1)"" | head -n 1 | cut -d "" "" -f4"; //string trojanCurrentVersion = client.RunCommand(sshcmd).Result;//不含字母v sshShellCommand = @"echo ""$(/usr/local/bin/trojan -v 2>&1)"" | head -n 1 | cut -d "" "" -f4"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string trojanCurrentVersion = currentShellCommandResult;//不含字母v @@ -4652,9 +3325,7 @@ namespace ProxySU //获取最新版本 sshShellCommand = @"curl -fsSL https://api.github.com/repos/trojan-gfw/trojan/releases/latest | grep tag_name | sed -E 's/.*""v(.*)"".*/\1/'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string trojanNewVersion = currentShellCommandResult;//不含字母v @@ -4674,50 +3345,33 @@ namespace ProxySU //****** "正在升级到最新版本......" ****** SetUpProgressBarProcessing(60); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartUpgradeNewVersion").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //****** "备份Trojan配置文件......" ****** SetUpProgressBarProcessing(80); currentStatus = Application.Current.FindResource("DisplayInstallInfo_BackTrojanConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); //string sshcmd = @"mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.bak"; //client.RunCommand(sshcmd); sshShellCommand = @"mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.bak"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //升级Trojan主程序 - //client.RunCommand("curl -o /tmp/trojan-quickstart.sh https://raw.githubusercontent.com/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"); + //client.RunCommand("curl -o /tmp/trojan-quickstart.sh https://{scriptGithubUrl}/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"); //client.RunCommand("yes | bash /tmp/trojan-quickstart.sh"); - sshShellCommand = @"curl -o /tmp/trojan-quickstart.sh https://raw.githubusercontent.com/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -o /tmp/trojan-quickstart.sh https://{scriptGithubUrl}/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"yes | bash /tmp/trojan-quickstart.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/trojan-quickstart.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //sshcmd = @"echo ""$(/usr/local/bin/trojan -v 2>&1)"" | head -n 1 | cut -d "" "" -f4"; sshShellCommand = @"echo ""$(/usr/local/bin/trojan -v 2>&1)"" | head -n 1 | cut -d "" "" -f4"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); trojanCurrentVersion = currentShellCommandResult;//不含字母v //trojanCurrentVersion = client.RunCommand(sshcmd).Result;//不含字母v @@ -4726,34 +3380,25 @@ namespace ProxySU //****** "恢复Trojan配置文件......" ****** SetUpProgressBarProcessing(90); currentStatus = Application.Current.FindResource("DisplayInstallInfo_RestoreTrojanConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); //sshcmd = @"rm -f /usr/local/etc/trojan/config.json"; //client.RunCommand(sshcmd); sshShellCommand = @"rm -f /usr/local/etc/trojan/config.json"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //sshcmd = @"mv /usr/local/etc/trojan/config.json.bak /usr/local/etc/trojan/config.json"; //client.RunCommand(sshcmd); sshShellCommand = @"mv /usr/local/etc/trojan/config.json.bak /usr/local/etc/trojan/config.json"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //****** "升级成功!当前已是最新版本!" ****** SetUpProgressBarProcessing(100); MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionOK").ToString()); //****** "升级成功!当前已是最新版本!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); } else { @@ -4761,11 +3406,7 @@ namespace ProxySU MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionFail").ToString()); //****** "升级失败,原因未知,请向开发者提问!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeNewVersionFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } } @@ -4773,11 +3414,8 @@ namespace ProxySU { //****** "升级取消,退出!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeVersionCancel").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); client.Disconnect(); return; } @@ -4791,11 +3429,7 @@ namespace ProxySU //****** "无需升级!退出!" ****** Application.Current.FindResource("DisplayInstallInfo_NotUpgradeVersion").ToString(); MessageBox.Show(currentStatus); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } client.Disconnect(); @@ -4808,10 +3442,7 @@ namespace ProxySU ProcessException(ex1.Message); //****** "主机登录失败!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -4864,20 +3495,24 @@ namespace ProxySU } //启动布署进程 installationDegree = 0; - Thread thread = new Thread(() => StartSetUpNaive(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + TextBoxMonitorCommandResults.Text = ""; + Thread thread = new Thread(() => StartSetUpNaive(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //登录远程主机布署NaiveProxy程序 - private void StartSetUpNaive(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void StartSetUpNaive(ConnectionInfo connectionInfo) { + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; + //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); try { @@ -4917,672 +3552,74 @@ namespace ProxySU //******"主机登录成功"****** SetUpProgressBarProcessing(3); currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - - //Thread.Sleep(1000); - } - - //******"检测是否运行在root权限下..."****** - SetUpProgressBarProcessing(5); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - 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) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(8); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //******"检测系统是否已经安装Caddy......"****** - SetUpProgressBarProcessing(10); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "Caddy......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - 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) - { - //****** "远程主机已安装Caddy,但不确定是否支持forward proxy,是否强制重新安装?" ****** - SetUpProgressBarProcessing(12); - MessageBoxResult messageBoxResult = MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_ExistedCaddy").ToString(), "", MessageBoxButton.YesNo, MessageBoxImage.Question); - if (messageBoxResult == MessageBoxResult.No) - { - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstallationCanceledExit").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //****** "请先行卸载Caddy或重装VPS系统!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_RemoveCaddyOrRebuiled").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //卸载Caddy代码 - } - } - else - { - //****** "检测结果:未安装Caddy!" ****** - SetUpProgressBarProcessing(12); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_NotInstalledCaddy").ToString(); - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); } - //******"检测系统是否符合安装要求......"****** - SetUpProgressBarProcessing(14); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_CheckSystemRequirements").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //Thread.Sleep(1000); + //检测是否已安装代理 8--10 + functionResult = SoftInstalledIsNoYes(client, "caddy", @"/usr/bin/caddy"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"uname -m"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测关闭Selinux及系统组件是否齐全(apt/yum/dnf/systemctl)11--30 + //安装依赖软件,检测端口,防火墙开启端口 + functionResult = ShutDownSelinuxAndSysComponentsDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } + + //检测域名是否解析到当前IP上 34---36 + functionResult = DomainResolutionCurrentIPDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - string resultCmd = currentShellCommandResult; - if (resultCmd.Contains("x86_64") == false) - { - //******"请在x86_64系统中安装Trojan" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_PleaseInstallSoftAtX64").ToString()); - //****** "系统环境不满足要求,安装失败!!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_MissingSystemComponents").ToString(); - 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值为真, - 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); - - SetUpProgressBarProcessing(16); - - 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的系统才能安装。 - if ((getApt && getDnf && getYum && getZypper) || getSystemd) - { - //******"系统缺乏必要的安装组件如:apt||dnf||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_MissingSystemComponents").ToString()); - - //******"系统环境不满足要求,安装失败!!"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_MissingSystemComponents").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(18); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SystemRequirementsOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //设置安装软件所用的命令格式 - //为假则表示系统有相应的组件。 - if (getApt == false) - { - sshCmdUpdate = @"apt -qq update"; - sshCmdInstall = @"apt -y -qq install "; - } - else if (getDnf == false) - { - sshCmdUpdate = @"dnf -q makecache"; - sshCmdInstall = @"dnf -y -q install "; - } - else if (getYum == false) - { - sshCmdUpdate = @"yum -q makecache"; - sshCmdInstall = @"yum -y -q install "; - } - else if (getZypper == false) - { - - sshCmdUpdate = @"zypper ref"; - sshCmdInstall = @"zypper -y install "; - } - //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 - - if (getGetenforce == false) - { - 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) - { - //******"检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中......"****** - SetUpProgressBarProcessing(20); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableSELinux").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - 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);//显示命令执行的结果 - - //******"修改完毕!"****** - SetUpProgressBarProcessing(22); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SELinuxModifyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - } - //安装所需软件 - - //****** "正在安装依赖的软件......" ****** - SetUpProgressBarProcessing(28); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstallRelySoft").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}curl libnss3 xz-utils lsof unzip"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //****** "安装完毕!OK!" ****** - SetUpProgressBarProcessing(32); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SoftInstalledOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //****** "正在检测域名是否解析到当前VPS的IP上......" ****** - SetUpProgressBarProcessing(36); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestDomainResolve").ToString(); - 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; - - 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) - { - //****** "解析正确!OK!" ****** - SetUpProgressBarProcessing(40); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DomainResolveOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - } - else - { - //****** "域名未能正确解析到当前VPS的IP上!安装失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorDomainResolve").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //****** "域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorDomainResolve").ToString()); - client.Disconnect(); - return; - } - - //****** "检测端口占用情况......" ****** - SetUpProgressBarProcessing(45); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestPortUsed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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 = Application.Current.FindResource("DisplayInstallInfo_ErrorPortUsedFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - - //****** "正在释放80/443端口......" ****** - SetUpProgressBarProcessing(50); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ReleasePort").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - if (String.IsNullOrEmpty(testPort443) == false) - { - string[] cmdResultArry443 = testPort443.Split(' '); - - 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);//显示命令执行的结果 - - } - - if (String.IsNullOrEmpty(testPort80) == false) - { - string[] cmdResultArry80 = testPort80.Split(' '); - - 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);//显示命令执行的结果 - - } - //****** "80/443端口释放完毕!" ****** - SetUpProgressBarProcessing(58); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ReleasePortOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "检测结果:未被占用!" ****** - SetUpProgressBarProcessing(59); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_PortNotUsed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } //****** "系统环境检测完毕,符合安装要求,开始布署......" ****** SetUpProgressBarProcessing(60); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstalling").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); + //Caddy安装与检测安装是否成功 61--66 + functionResult = CaddyInstall(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //打开防火墙端口 - //****** "开启防火墙相应端口......" ****** - SetUpProgressBarProcessing(61); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_OpenFireWallPort").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) - { - 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) - { - - 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);//显示命令执行的结果 - - } - //****** "正在安装Caddy.....". ****** - SetUpProgressBarProcessing(65); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddy").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //安装Caddy - //为假则表示系统有相应的组件。 - if (getApt == false) - { - - 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);//显示命令执行的结果 - SetUpProgressBarProcessing(74); - } - else if (getDnf == false) - { - - 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);//显示命令执行的结果 - SetUpProgressBarProcessing(74); - } - else if (getYum == false) - { - - 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);//显示命令执行的结果 - SetUpProgressBarProcessing(74); - } - //else if (getZypper == false) - //{ - // client.RunCommand("zypper ref"); - // client.RunCommand("zypper -y install curl"); - //} - 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")) - { - - //****** "安装Caddy失败!" ****** - MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_ErrorInstallCaddyFail").ToString()); - //****** "安装Caddy失败!" ****** - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "Caddy安装成功!" ****** - SetUpProgressBarProcessing(75); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstalledCaddyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"systemctl enable caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } //使用带插件的Caddy替换 //****** "正在为NaiveProxy升级服务端!" ****** - SetUpProgressBarProcessing(76); + //SetUpProgressBarProcessing(76); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeNaiveProxy").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); - - 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 = $"curl -o /tmp/caddy.zip https://{scriptGithubUrl}/proxysu/Resources/master/Caddy2/caddy20200816.zip"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"yes | unzip -o /tmp/caddy.zip"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"chmod +x ./caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); 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);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"cp caddy /usr/bin/"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/caddy.zip caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //****** "升级完毕,OK!" ****** - SetUpProgressBarProcessing(79); + //SetUpProgressBarProcessing(79); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UpgradeNaiveProxyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); //****** "上传Caddy配置文件......" ****** - SetUpProgressBarProcessing(80); + SetUpProgressBarProcessing(67); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadCaddyConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //生成服务端配置 - - string caddyConfig = @"TemplateConfg\naive\naive_server_config.json"; using (StreamReader reader = File.OpenText(caddyConfig)) { @@ -5608,105 +3645,19 @@ namespace ProxySU File.Delete(@"config.json"); //****** Caddy配置文件上传成功,OK! ****** - SetUpProgressBarProcessing(83); + SetUpProgressBarProcessing(70); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadCaddyConfigOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); 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);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"systemctl daemon-reload"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //****** 正在启动Caddy...... ****** - SetUpProgressBarProcessing(85); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyService").ToString(); - 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);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) - { - //****** "Caddy启动成功!" ****** - SetUpProgressBarProcessing(89); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Caddy启动失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - //****** "正在启动Caddy(第二次尝试)!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceSecond").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - sshShellCommand = @"systemctl restart caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) - { - //****** "Caddy启动成功!" ****** - SetUpProgressBarProcessing(89); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Caddy启动失败(第二次)!退出安装!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceSecondFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - //****** "Caddy启动失败,原因未知!请向开发者问询!" ****** - MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_CaddyServiceFailedExit").ToString()); - return; - } - } + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + //程序启动检测Caddy + functionResult = SoftStartDetect(client, "caddy", @"/usr/bin/caddy"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } ////设置伪装网站 //if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) @@ -5718,197 +3669,83 @@ namespace ProxySU //Thread.Sleep(2000); //****** "正在优化网络参数......" ****** - SetUpProgressBarProcessing(90); + SetUpProgressBarProcessing(80); currentStatus = Application.Current.FindResource("DisplayInstallInfo_OptimizeNetwork").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //优化网络参数 sshShellCommand = @"bash -c 'echo ""fs.file-max = 51200"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.core.rmem_max = 67108864"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.core.wmem_max = 67108864"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.core.rmem_default = 65536"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.core.wmem_default = 65536"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.core.netdev_max_backlog = 4096"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.core.somaxconn = 4096"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_syncookies = 1"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_tw_reuse = 1"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_tw_recycle = 0"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_fin_timeout = 30"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_keepalive_time = 1200"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.ip_local_port_range = 10000 65000"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_max_syn_backlog = 4096"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_max_tw_buckets = 5000"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_rmem = 4096 87380 67108864"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_wmem = 4096 65536 67108864"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash -c 'echo ""net.ipv4.tcp_mtu_probing = 1"" >> /etc/sysctl.conf'"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"sysctl -p"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //****** "优化网络参数,OK!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_OptimizeNetworkOK").ToString(); ; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); + //检测BBR,满足条件并启动 90--95 + functionResult = DetectBBRandEnable(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //测试BBR条件,若满足则启用 - //****** "BBR测试......" ****** - SetUpProgressBarProcessing(94); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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]); - 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) - { - //****** "正在启用BBR......" ****** - SetUpProgressBarProcessing(95); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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) - { - //****** "BBR已经启用了!" ****** - SetUpProgressBarProcessing(97); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRisEnabled").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - else - { - //****** "系统不满足启用BBR的条件,启用失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } + client.Disconnect();//断开服务器ssh连接 //****** "生成客户端配置......" ****** - SetUpProgressBarProcessing(98); + SetUpProgressBarProcessing(96); currentStatus = Application.Current.FindResource("DisplayInstallInfo_GenerateClientConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); if (!Directory.Exists("naive_config"))//如果不存在就创建file文件夹      { Directory.CreateDirectory("naive_config");//创建该文件夹   @@ -5925,16 +3762,12 @@ namespace ProxySU sw.Write(clientJson.ToString()); } } - client.Disconnect(); + //****** "NaiveProxy安装成功,祝你玩的愉快!!" ****** SetUpProgressBarProcessing(100); currentStatus = "NaiveProxy" + Application.Current.FindResource("DisplayInstallInfo_ProxyInstalledOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //显示服务端连接参数 proxyType = "NaiveProxy"; @@ -6041,20 +3874,24 @@ namespace ProxySU installationDegree = 0; - Thread thread = new Thread(() => StartSetUpSSR(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + TextBoxMonitorCommandResults.Text = ""; + Thread thread = new Thread(() => StartSetUpSSR(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //登录远程主机布署SSR+TLS+Caddy程序 - private void StartSetUpSSR(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void StartSetUpSSR(ConnectionInfo connectionInfo) { + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; + //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); try { @@ -6094,728 +3931,82 @@ namespace ProxySU //******"主机登录成功"****** SetUpProgressBarProcessing(3); currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } - //******"检测是否运行在root权限下..."****** - SetUpProgressBarProcessing(5); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"id -u"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测是否已安装代理 8--10 + functionResult = SoftInstalledIsNoYes(client, "server.py", @"/usr/local/shadowsocks/server.py"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - string testRootAuthority = currentShellCommandResult; - if (testRootAuthority.Equals("0\n") == false) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(8); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测关闭Selinux及系统组件是否齐全(apt/yum/dnf/systemctl)11--30 + //安装依赖软件,检测端口,防火墙开启端口 + functionResult = ShutDownSelinuxAndSysComponentsDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - } + //检测域名是否解析到当前IP上 34---36 + functionResult = DomainResolutionCurrentIPDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //******"检测系统是否已经安装SSR......"****** - SetUpProgressBarProcessing(10); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "SSR......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"if [ -f /usr/local/shadowsocks/server.py ];then echo '1';else echo '0'; fi"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - string resultCmdTestTrojanInstalled = currentShellCommandResult; - - if (resultCmdTestTrojanInstalled.Contains("1") == true) - { - MessageBoxResult messageBoxResult = MessageBox.Show( - //******"远程主机已安装"****** - Application.Current.FindResource("MessageBoxShow_ExistedSoft").ToString() + - "SSR" + - //******",是否强制重新安装?"****** - Application.Current.FindResource("MessageBoxShow_ForceInstallSoft").ToString(), "", MessageBoxButton.YesNo, MessageBoxImage.Question); - if (messageBoxResult == MessageBoxResult.No) - { - //******"安装取消,退出"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstallationCanceledExit").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //******"已选择强制安装SSR!"****** - SetUpProgressBarProcessing(11); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ForceInstallSoft").ToString() + "SSR!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - } - } - else - { - //******"检测结果:未安装SSR!"****** - SetUpProgressBarProcessing(12); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "SSR!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus);//显示命令执行的结果 - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - //******"检测系统是否符合安装要求......"****** - SetUpProgressBarProcessing(14); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_CheckSystemRequirements").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - - //检测系统是否支持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); - - SetUpProgressBarProcessing(16); - - 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的系统才能安装。 - if ((getApt && getDnf && getYum && getZypper) || getSystemd) - { - //******"系统缺乏必要的安装组件如:apt||dnf||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_MissingSystemComponents").ToString()); - - //******"系统环境不满足要求,安装失败!!"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_MissingSystemComponents").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(18); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SystemRequirementsOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //设置安装软件所用的命令格式 - //为假则表示系统有相应的组件。 - - if (getApt == false) - { - sshCmdUpdate = @"apt -qq update"; - sshCmdInstall = @"apt -y -qq install "; - } - else if (getDnf == false) - { - sshCmdUpdate = @"dnf -q makecache"; - sshCmdInstall = @"dnf -y -q install "; - } - else if (getYum == false) - { - sshCmdUpdate = @"yum -q makecache"; - sshCmdInstall = @"yum -y -q install "; - } - else if (getZypper == false) - { - sshCmdUpdate = @"zypper ref"; - sshCmdInstall = @"zypper -y install "; - } - - //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 - if (getGetenforce == false) - { - 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) - { - //******"检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中......"****** - SetUpProgressBarProcessing(20); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableSELinux").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - 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);//显示命令执行的结果 - - //******"修改完毕!"****** - SetUpProgressBarProcessing(22); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SELinuxModifyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - } - - //****** "正在检测域名是否解析到当前VPS的IP上......" ****** - SetUpProgressBarProcessing(28); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestDomainResolve").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //在相应系统内安装curl(如果没有安装curl) - if (string.IsNullOrEmpty(client.RunCommand("command -v curl").Result) == true) - { - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}curl"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - SetUpProgressBarProcessing(36); - //检测域名是否解析正确 - 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; - - 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) - { - //****** "解析正确!OK!" ****** - SetUpProgressBarProcessing(40); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DomainResolveOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "域名未能正确解析到当前VPS的IP上!安装失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorDomainResolve").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //****** "域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorDomainResolve").ToString()); - client.Disconnect(); - return; - } - - //检测是否安装lsof - if (string.IsNullOrEmpty(client.RunCommand("command -v lsof").Result) == true) - { - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}lsof"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //****** "检测端口占用情况......" ****** - SetUpProgressBarProcessing(45); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestPortUsed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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) - { - //****** "80/443端口之一,或全部被占用,将强制停止占用80/443端口的程序?" ****** - MessageBoxResult dialogResult = MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorPortUsed").ToString(), "Stop application", MessageBoxButton.YesNo); - if (dialogResult == MessageBoxResult.No) - { - //****** "端口被占用,安装失败......" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorPortUsedFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - - //****** "正在释放80/443端口......" ****** - SetUpProgressBarProcessing(48); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ReleasePort").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - if (String.IsNullOrEmpty(testPort443) == false) - { - string[] cmdResultArry443 = testPort443.Split(' '); - - 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);//显示命令执行的结果 - - } - - if (String.IsNullOrEmpty(testPort80) == false) - { - string[] cmdResultArry80 = testPort80.Split(' '); - - 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);//显示命令执行的结果 - - } - //****** "80/443端口释放完毕!" ****** - SetUpProgressBarProcessing(51); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ReleasePortOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "检测结果:未被占用!" ****** - SetUpProgressBarProcessing(52); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_PortNotUsed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } //****** "系统环境检测完毕,符合安装要求,开始布署......" ****** - SetUpProgressBarProcessing(53); + SetUpProgressBarProcessing(37); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstalling").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //****** "开启防火墙相应端口......" ****** - SetUpProgressBarProcessing(54); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_OpenFireWallPort").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) - { - - 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) - { - 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);//显示命令执行的结果 - - } - - //处理极其少见的xz-utils未安装的情况 - SetUpProgressBarProcessing(56); - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}xz-utils"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); //下载安装脚本安装 //****** "正在安装SSR......" ****** - SetUpProgressBarProcessing(58); + SetUpProgressBarProcessing(38); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + "SSR......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); - - sshShellCommand = @"curl -o /tmp/ssr.sh https://raw.githubusercontent.com/proxysu/shellscript/master/ssr/ssr.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -o /tmp/ssr.sh https://{scriptGithubUrl}/proxysu/shellscript/master/ssr/ssr.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"yes | bash /tmp/ssr.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/ssr.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + //程序是否安装成功检测并设置开机启动 41--43 + functionResult = SoftInstalledSuccessOrFail(client, "server.py", @"/usr/local/shadowsocks/server.py"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"if [ -f /usr/local/shadowsocks/server.py ];then echo '1';else echo '0'; fi"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - string installResult = currentShellCommandResult; - - if (!installResult.Contains("1")) - { - //****** "安装失败,官方脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString()); - //****** "安装失败,官方脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "SSR安装成功!" ****** - SetUpProgressBarProcessing(61); - currentStatus = "SSR" + Application.Current.FindResource("DisplayInstallInfo_SoftInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //设置开机自启动 - sshShellCommand = @"systemctl enable ssr"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //sshShellCommand = @"mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.1"; - //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - //currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + //****** "安装完毕,上传配置文件......" ****** - SetUpProgressBarProcessing(62); + SetUpProgressBarProcessing(44); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadSoftConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //生成服务端配置 - //serverConfig = @"/etc/shadowsocks.json"; string upLoadPath = @"/etc/shadowsocks.json"; + //设置指向Caddy监听的随机端口 - //Random random = new Random(); randomCaddyListenPort = GetRandomPort(); string randomSSRListenPortStr = randomCaddyListenPort.ToString(); sshShellCommand = $"sed -i 's/8800/{randomSSRListenPortStr}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //设置密码 sshShellCommand = $"sed -i 's/##password##/{ReceiveConfigurationParameters[2]}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //****** "安装Caddy......" ****** - SetUpProgressBarProcessing(65); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallCaddy").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //安装Caddy - //为假则表示系统有相应的组件。 - if (getApt == false) - { - 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);//显示命令执行的结果 - SetUpProgressBarProcessing(74); - } - else if (getDnf == false) - { - - 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);//显示命令执行的结果 - SetUpProgressBarProcessing(74); - } - else if (getYum == false) - { - 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);//显示命令执行的结果 - SetUpProgressBarProcessing(74); - } - - sshShellCommand = @"find / -name caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/bin/caddy")) - { - //****** "安装Caddy失败!" ****** - MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_ErrorInstallCaddyFail").ToString()); - //****** "安装Caddy失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorInstallCaddyFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - - //****** "Caddy安装成功!" ****** - SetUpProgressBarProcessing(75); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstalledCaddyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"systemctl enable caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //Caddy安装与检测安装是否成功 61--66 + functionResult = CaddyInstall(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } //****** "上传Caddy配置文件......" ****** - SetUpProgressBarProcessing(80); + SetUpProgressBarProcessing(67); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadCaddyConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); sshShellCommand = @"mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string caddyConfig = @"TemplateConfg\ssr\ssr_tls.caddyfile"; upLoadPath = @"/etc/caddy/Caddyfile"; @@ -6826,285 +4017,41 @@ namespace ProxySU string randomCaddyListenPortStr = randomCaddyListenPort.ToString(); sshShellCommand = $"sed -i 's/8800/{randomCaddyListenPortStr}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //设置域名 - sshShellCommand = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/g' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //设置伪装网站 if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) { sshShellCommand = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); } //****** "Caddy配置文件上传成功,OK!" ****** - SetUpProgressBarProcessing(83); + SetUpProgressBarProcessing(70); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadCaddyConfigOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); + //程序启动检测Caddy + functionResult = SoftStartDetect(client, "caddy", @"/usr/bin/caddy"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //****** "正在启动Caddy......" ****** - SetUpProgressBarProcessing(85); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyService").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //程序启动检测SSR + functionResult = SoftStartDetect(client, "ssr", @"/usr/bin/ssr"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //Thread.Sleep(1000); - //启动Caddy服务 - sshShellCommand = @"systemctl restart caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测BBR,满足条件并启动 90--95 + functionResult = DetectBBRandEnable(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) - { - //****** "Caddy启动成功!" ****** - SetUpProgressBarProcessing(89); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Caddy启动失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - //****** "正在启动Caddy(第二次尝试)!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceSecond").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - sshShellCommand = @"systemctl restart caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) - { - //****** "Caddy启动成功!" ****** - SetUpProgressBarProcessing(89); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Caddy启动失败(第二次)!退出安装!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceSecondFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - //****** "Caddy启动失败,原因未知!请向开发者问询!" ****** - MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_CaddyServiceFailedExit").ToString()); - return; - } - } - - //****** "正在启动SSR......" ****** - SetUpProgressBarProcessing(90); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartSoft").ToString() + "SSR......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //启动SSR服务 - sshShellCommand = @"systemctl restart ssr"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep ssr"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("/usr/bin/ssr") == true) - { - //****** "SSR启动成功!" ****** - SetUpProgressBarProcessing(93); - currentStatus = "SSR" + Application.Current.FindResource("DisplayInstallInfo_StartSoftOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "SSR启动失败!" ****** - currentStatus = "SSR" + Application.Current.FindResource("DisplayInstallInfo_StartSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(3000); - - //****** "正在第二次尝试启动SSR!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartSoftSecond").ToString() + "SSR!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(3000); - sshShellCommand = @"systemctl restart ssr"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep ssr"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("usr/bin/ssr") == true) - { - //****** "SSR启动成功!" ****** - SetUpProgressBarProcessing(93); - currentStatus = "SSR" + Application.Current.FindResource("DisplayInstallInfo_StartSoftOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "SSR启动失败(第二次)!退出安装!" ****** - currentStatus = "SSR" + Application.Current.FindResource("DisplayInstallInfo_StartSoftSecondFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - //****** "SSR启动失败,原因未知!请向开发者问询!" ****** - MessageBox.Show("SSR" + Application.Current.FindResource("DisplayInstallInfo_StartSoftFailedExit").ToString()); - return; - } - } - - - //测试BBR条件,若满足则启用 - //****** "BBR测试......" ****** - SetUpProgressBarProcessing(94); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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]); - - 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) - { - //****** "正在启用BBR......" ****** - SetUpProgressBarProcessing(95); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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) - { - //****** "BBR已经启用了!" ****** - SetUpProgressBarProcessing(97); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRisEnabled").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - else - { - //****** "系统不满足启用BBR的条件,启用失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } client.Disconnect();//断开服务器ssh连接 //****** "生成客户端配置......" ****** - SetUpProgressBarProcessing(98); + SetUpProgressBarProcessing(96); currentStatus = Application.Current.FindResource("DisplayInstallInfo_GenerateClientConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); if (!Directory.Exists("ssr_config"))//如果不存在就创建file文件夹      { Directory.CreateDirectory("ssr_config");//创建该文件夹   @@ -7114,11 +4061,7 @@ namespace ProxySU //****** "SSR+TLS+Caddy安装成功,祝你玩的愉快!!" ****** SetUpProgressBarProcessing(100); currentStatus = "SSR+TLS+Caddy" + Application.Current.FindResource("DisplayInstallInfo_ProxyInstalledOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //显示服务端连接参数 proxyType = "SSR"; @@ -7320,26 +4263,26 @@ namespace ProxySU testDomain = true; } - //Thread thread installationDegree = 0; - Thread thread = new Thread(() => StartSetUpSS(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + TextBoxMonitorCommandResults.Text = ""; + Thread thread = new Thread(() => StartSetUpSS(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); - // Task task = new Task(() => StartSetUpRemoteHost(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing, serverConfig, clientConfig, upLoadPath)); - //task.Start(); } //登录远程主机布署SS程序 - private void StartSetUpSS(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void StartSetUpSS(ConnectionInfo connectionInfo) { + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); try { @@ -7379,582 +4322,50 @@ namespace ProxySU //******"主机登录成功"****** SetUpProgressBarProcessing(3); currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } - //******"检测是否运行在root权限下..."****** - SetUpProgressBarProcessing(5); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"id -u"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测是否已安装代理 8--10 + functionResult = SoftInstalledIsNoYes(client, "ss-server", @"/usr/local/bin/ss-server"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - string testRootAuthority = currentShellCommandResult; - if (testRootAuthority.Equals("0\n") == false) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(8); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - //******"检测系统是否已经安装SS......"****** - SetUpProgressBarProcessing(10); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "SS......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"find / -name ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - string resultCmdTestV2rayInstalled = currentShellCommandResult; - if (resultCmdTestV2rayInstalled.Contains("/usr/local/bin/ss-server") == true) - { - //******"远程主机已安装SS,是否强制重新安装?"****** - string messageShow = Application.Current.FindResource("MessageBoxShow_ExistedSoft").ToString() + - "SS" + - Application.Current.FindResource("MessageBoxShow_ForceInstallSoft").ToString(); - MessageBoxResult messageBoxResult = MessageBox.Show(messageShow, "", MessageBoxButton.YesNo, MessageBoxImage.Question); - if (messageBoxResult == MessageBoxResult.No) - { - //******"安装取消,退出"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstallationCanceledExit").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //******"已选择强制安装SS!"****** - SetUpProgressBarProcessing(12); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ForceInstallSoft").ToString() + "SS!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"systemctl stop ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - } - else - { - //******"检测结果:未安装SS!"****** - SetUpProgressBarProcessing(12); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "SS!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - //******"检测系统是否符合安装要求......"****** - SetUpProgressBarProcessing(14); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_CheckSystemRequirements").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //检测系统是否支持yum 或 apt-get或zypper,且支持Systemd - //如果不存在组件,则命令结果为空,string.IsNullOrEmpty值为真, - - 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); - - SetUpProgressBarProcessing(16); - - 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的系统才能安装。 - if ((getApt && getDnf && getYum && getZypper) || getSystemd) - { - //******"系统缺乏必要的安装组件如:apt||dnf||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_MissingSystemComponents").ToString()); - - //******"系统环境不满足要求,安装失败!!"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_MissingSystemComponents").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - SetUpProgressBarProcessing(18); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SystemRequirementsOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - //设置安装软件所用的命令格式 - if (getApt == false) - { - sshCmdUpdate = @"apt -qq update"; - sshCmdInstall = @"apt -y -qq install "; - } - else if (getDnf == false) - { - sshCmdUpdate = @"dnf -q makecache"; - sshCmdInstall = @"dnf -y -q install "; - } - else if (getYum == false) - { - sshCmdUpdate = @"yum -q makecache"; - sshCmdInstall = @"yum -y -q install "; - } - else if (getZypper == false) - { - sshCmdUpdate = @"zypper ref"; - sshCmdInstall = @"zypper -y install "; - } - - //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 - if (getGetenforce == false) - { - 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) - { - //******"检测到系统启用SELinux,且工作在严格模式下,需改为宽松模式!修改中......"****** - SetUpProgressBarProcessing(20); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableSELinux").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - 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);//显示命令执行的结果 - //******"修改完毕!"****** - SetUpProgressBarProcessing(22); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_SELinuxModifyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - } - //在相应系统内安装curl(如果没有安装curl)--此为依赖软件 - if (String.IsNullOrEmpty(client.RunCommand("command -v curl").Result) == true || String.IsNullOrEmpty(client.RunCommand("command -v wget").Result) == true) - { - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}curl"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //在相应系统内安装wget(如果没有安装wget)--此为依赖软件 - if (String.IsNullOrEmpty(client.RunCommand("command -v wget").Result) == true) - { - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}wget"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } + //检测关闭Selinux及系统组件是否齐全(apt/yum/dnf/systemctl)11--30 + //安装依赖软件,检测端口,防火墙开启端口 + functionResult = ShutDownSelinuxAndSysComponentsDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } //如果使用是TLS模式,需要检测域名解析是否正确 if (testDomain == true) { - //****** "正在检测域名是否解析到当前VPS的IP上......" ****** - SetUpProgressBarProcessing(28); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestDomainResolve").ToString(); - 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; - - 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) - { - //****** "解析正确!OK!" ****** - SetUpProgressBarProcessing(32); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DomainResolveOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "域名未能正确解析到当前VPS的IP上!安装失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorDomainResolve").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - //****** "域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorDomainResolve").ToString()); - client.Disconnect(); - return; - } - - //检测是否安装lsof - if (string.IsNullOrEmpty(client.RunCommand("command -v lsof").Result) == true) - { - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}lsof"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - //****** "检测端口占用情况......" ****** - SetUpProgressBarProcessing(34); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestPortUsed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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) - { - //****** "80/443端口之一,或全部被占用,将强制停止占用80/443端口的程序?" ****** - MessageBoxResult dialogResult = MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorPortUsed").ToString(), "Stop application", MessageBoxButton.YesNo); - if (dialogResult == MessageBoxResult.No) - { - //****** "端口被占用,安装失败......" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorPortUsedFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - client.Disconnect(); - return; - } - //****** "正在释放80/443端口......" ****** - SetUpProgressBarProcessing(37); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ReleasePort").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - if (String.IsNullOrEmpty(testPort443) == false) - { - string[] cmdResultArry443 = testPort443.Split(' '); - 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);//显示命令执行的结果 - - } - - if (String.IsNullOrEmpty(testPort80) == false) - { - string[] cmdResultArry80 = testPort80.Split(' '); - 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);//显示命令执行的结果 - - } - //****** "80/443端口释放完毕!" ****** - SetUpProgressBarProcessing(39); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ReleasePortOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "检测结果:未被占用!" ****** - SetUpProgressBarProcessing(41); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_PortNotUsed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } + //检测域名是否解析到当前IP上 34---36 + functionResult = DomainResolutionCurrentIPDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } } //****** "系统环境检测完毕,符合安装要求,开始布署......" ****** - SetUpProgressBarProcessing(43); + SetUpProgressBarProcessing(37); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstalling").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //****** "开启防火墙相应端口......" ****** - SetUpProgressBarProcessing(44); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_OpenFireWallPort").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - string openFireWallPort = ReceiveConfigurationParameters[1]; - if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) - { - if (String.Equals(openFireWallPort, "443")) - { - 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=80/udp --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 = @"firewall-cmd --zone=public --add-port=443/udp --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);//显示命令执行的结果 - } - else - { - sshShellCommand = $"firewall-cmd --zone=public --add-port={openFireWallPort}/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={openFireWallPort}/udp --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);//显示命令执行的结果 - - } - } - else if (String.IsNullOrEmpty(client.RunCommand("command -v ufw").Result) == false) - { - if (String.Equals(openFireWallPort, "443")) - { - sshShellCommand = @"ufw allow 80/tcp"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"ufw allow 80/udp"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"ufw allow 443/tcp"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"ufw allow 443/udp"; - 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);//显示命令执行的结果 - - } - else - { - sshShellCommand = $"ufw allow {openFireWallPort}/tcp"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"ufw allow {openFireWallPort}/udp"; - 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);//显示命令执行的结果 - - } - } + MainWindowsShowInfo(currentStatus); //下载安装脚本安装 //****** "正在安装SS,使用编译方式,时间稍长,请耐心等待............" ****** - SetUpProgressBarProcessing(46); + SetUpProgressBarProcessing(38); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + "SS," + Application.Current.FindResource("DisplayInstallInfo_ExplainBuildSS").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); - - sshShellCommand = @"curl -o /tmp/install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/ss/ss-install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -o /tmp/install.sh https://{scriptGithubUrl}/proxysu/shellscript/master/ss/ss-install.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"yes | bash /tmp/install.sh"; TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 //****** "编译中,请耐心等待............" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_CompilingSS").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); Thread threadWaitSScompile = new Thread(() => MonitorCompileSSprocess()); threadWaitSScompile.SetApartmentState(ApartmentState.STA); @@ -7967,62 +4378,19 @@ namespace ProxySU TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"rm -f /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - - sshShellCommand = @"find / -name ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - string installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/local/bin/ss-server")) - { - //****** "安装失败,脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString()); - //****** "安装失败,脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "SS安装成功!" ****** - SetUpProgressBarProcessing(52); - currentStatus = "SS" + Application.Current.FindResource("DisplayInstallInfo_SoftInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"systemctl enable ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - - sshShellCommand = @"mv /etc/shadowsocks-libev/config.json /etc/shadowsocks-libev/config.json.1"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //程序是否安装成功检测并设置开机启动 41--43 + functionResult = SoftInstalledSuccessOrFail(client, "ss-server", @"/usr/local/bin/ss-server"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } //****** "上传配置文件......" ****** - SetUpProgressBarProcessing(53); + SetUpProgressBarProcessing(44); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadSoftConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); + sshShellCommand = @"mv /etc/shadowsocks-libev/config.json /etc/shadowsocks-libev/config.json.1"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //string getIpv4 = client.RunCommand(@"curl -4 ip.sb").Result; //string getIpv6 = client.RunCommand(@"wget -qO- -t1 -T2 ipv6.icanhazip.com").Result; @@ -8124,58 +4492,23 @@ namespace ProxySU else if (String.Equals(ReceiveConfigurationParameters[0], "CloakPluginSS") == true) { //****** "正在安装 Cloak-Plugin......" ****** - SetUpProgressBarProcessing(54); + SetUpProgressBarProcessing(48); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + " Cloak-Plugin......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); + sshShellCommand = $"curl -o /tmp/install.sh https://{scriptGithubUrl}/proxysu/shellscript/master/ss/ss-plugins/cloak-plugin-install.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - sshShellCommand = @"curl -o /tmp/install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/ss/ss-plugins/cloak-plugin-install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"yes | bash /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + //程序是否安装成功检测并设置开机启动 41--43 + functionResult = SoftInstalledSuccessOrFail(client, "cloak-plugin-server", @"/usr/local/bin/cloak-plugin-server"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"find / -name cloak-plugin-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/local/bin/cloak-plugin-server")) - { - //****** "安装失败,脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString()); - //****** "安装失败,脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "cloak-plugin-server安装成功!" ****** - currentStatus = "cloak-plugin-server" + Application.Current.FindResource("DisplayInstallInfo_SoftInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } string bypassUID = client.RunCommand(@"/usr/local/bin/cloak-plugin-server -u").Result.TrimEnd('\r', '\n'); string generateKey = client.RunCommand(@"/usr/local/bin/cloak-plugin-server -k").Result.TrimEnd('\r', '\n'); @@ -8206,226 +4539,87 @@ namespace ProxySU if (String.Equals(ssPluginType, "obfs-server")) { //****** "正在安装 Simple-obfs Plugin......" ****** - SetUpProgressBarProcessing(54); + SetUpProgressBarProcessing(48); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + " Simple-obfs Plugin......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); + + sshShellCommand = $"curl -o /tmp/install.sh https://{scriptGithubUrl}/proxysu/shellscript/master/ss/ss-plugins/obfs-install.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - sshShellCommand = @"curl -o /tmp/install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/ss/ss-plugins/obfs-install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"yes | bash /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + //程序是否安装成功检测并设置开机启动 41--43 + functionResult = SoftInstalledSuccessOrFail(client, "obfs-server", @"/usr/local/bin/obfs-server"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"find / -name obfs-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/local/bin/obfs-server")) - { - //****** "安装失败,脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString()); - //****** "安装失败,脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "Simple-obfs Plugin安装成功!" ****** - - currentStatus = "Simple-obfs Plugin" + Application.Current.FindResource("DisplayInstallInfo_SoftInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } + } else if (String.Equals(ssPluginType, "v2ray-plugin")) { //****** "正在安装 V2Ray-Plugin......" ****** - SetUpProgressBarProcessing(54); + SetUpProgressBarProcessing(48); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + " V2Ray-Plugin......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); + sshShellCommand = $"curl -o /tmp/install.sh https://{scriptGithubUrl}/proxysu/shellscript/master/ss/ss-plugins/v2ray-plugin-install.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - sshShellCommand = @"curl -o /tmp/install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/ss/ss-plugins/v2ray-plugin-install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"yes | bash /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + //程序是否安装成功检测并设置开机启动 41--43 + functionResult = SoftInstalledSuccessOrFail(client, "v2ray-plugin", @"/usr/local/bin/v2ray-plugin"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"find / -name v2ray-plugin"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/local/bin/v2ray-plugin")) - { - //****** "安装失败,脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString()); - //****** "安装失败,脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "v2ray-plugin安装成功!" ****** - currentStatus = "v2ray-plugin" + Application.Current.FindResource("DisplayInstallInfo_SoftInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } } else if (String.Equals(ssPluginType, "kcptun-plugin-server")) { //****** "正在安装 Kcptun-Plugin......" ****** - SetUpProgressBarProcessing(54); + SetUpProgressBarProcessing(48); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + " Kcptun-Plugin......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); + sshShellCommand = $"curl -o /tmp/install.sh https://{scriptGithubUrl}/proxysu/shellscript/master/ss/ss-plugins/kcptun-plugin-install.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - sshShellCommand = @"curl -o /tmp/install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/ss/ss-plugins/kcptun-plugin-install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"yes | bash /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + //程序是否安装成功检测并设置开机启动 41--43 + functionResult = SoftInstalledSuccessOrFail(client, "kcptun-plugin-server", @"/usr/local/bin/kcptun-plugin-server"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"find / -name kcptun-plugin-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/local/bin/kcptun-plugin-server")) - { - //****** "安装失败,脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString()); - //****** "安装失败,脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "kcptun-plugin-server安装成功!" ****** - currentStatus = "kcptun-plugin-server" + Application.Current.FindResource("DisplayInstallInfo_SoftInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } } else if (String.Equals(ssPluginType, "goquiet-plugin-server")) { //****** "正在安装 GoQuiet-Plugin......" ****** - SetUpProgressBarProcessing(54); + SetUpProgressBarProcessing(48); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + " GoQuiet-Plugin......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); + sshShellCommand = $"curl -o /tmp/install.sh https://{scriptGithubUrl}/proxysu/shellscript/master/ss/ss-plugins/goquiet-plugin-install.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - sshShellCommand = @"curl -o /tmp/install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/ss/ss-plugins/goquiet-plugin-install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 sshShellCommand = @"yes | bash /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f /tmp/install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + //程序是否安装成功检测并设置开机启动 41--43 + functionResult = SoftInstalledSuccessOrFail(client, "goquiet-plugin-server", @"/usr/local/bin/goquiet-plugin-server"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - sshShellCommand = @"find / -name goquiet-plugin-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/local/bin/goquiet-plugin-server")) - { - //****** "安装失败,脚本运行出错!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString()); - //****** "安装失败,脚本运行出错!" ****** - currentStatus = Application.Current.FindResource("MessageBoxShow_ErrorInstallSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - else - { - //****** "goquiet-plugin-server安装成功!" ****** - currentStatus = "goquiet-plugin-server" + Application.Current.FindResource("DisplayInstallInfo_SoftInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } } else if (String.Equals(ssPluginType, "cloak-plugin-server")) { @@ -8436,105 +4630,9 @@ namespace ProxySU //如果使用v2ray-plugin Quic模式,先要安装acme.sh,申请证书 if (String.Equals(ReceiveConfigurationParameters[0], "QuicSS") == true ) { - //****** "正在安装acme.sh......" ****** - SetUpProgressBarProcessing(55); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallAcmeSh").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //安装所依赖的软件 - sshShellCommand = $"{sshCmdUpdate}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = $"{sshCmdInstall}socat"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //解决搬瓦工CentOS缺少问题 - sshShellCommand = $"{sshCmdInstall}automake autoconf libtool"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - - sshShellCommand = @"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("Install success") == true) - { - //****** "acme.sh安装成功!" ****** - SetUpProgressBarProcessing(58); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_AcmeShInstallSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "acme.sh安装失败!原因未知,请向开发者提问!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorAcmeShInstallFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - return; - } - - sshShellCommand = @"cd ~/.acme.sh/"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - sshShellCommand = @"alias acme.sh=~/.acme.sh/acme.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //****** "申请域名证书......" ****** - SetUpProgressBarProcessing(60); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartApplyCert").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = $"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("Cert success") == true) - { - //****** "证书申请成功!" ****** - SetUpProgressBarProcessing(63); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ApplyCertSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "证书申请失败!原因未知,请向开发者提问!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ApplyCertFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - return; - } + //acme.sh安装与申请证书 51--57 + functionResult = AcmeShInstall(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } } @@ -8546,139 +4644,17 @@ namespace ProxySU || String.Equals(ReceiveConfigurationParameters[0], "CloakPluginSS") == true ) { - //****** "安装Caddy......" ****** - SetUpProgressBarProcessing(70); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallCaddy").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - //安装Caddy - //为假则表示系统有相应的组件。 - if (getApt == false) - { - - 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) - { - - 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) - { - - 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);//显示命令执行的结果 - - } - - sshShellCommand = @"find / -name caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - installResult = currentShellCommandResult; - - if (!installResult.Contains("/usr/bin/caddy")) - { - //****** "安装Caddy失败!" ****** - MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_ErrorInstallCaddyFail").ToString()); - //****** "安装Caddy失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorInstallCaddyFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - client.Disconnect(); - return; - } - //****** "Caddy安装成功!" ****** - SetUpProgressBarProcessing(75); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_InstalledCaddyOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"systemctl enable caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //Caddy安装 61--66 + functionResult = CaddyInstall(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } //****** "上传Caddy配置文件......" ****** - SetUpProgressBarProcessing(80); + SetUpProgressBarProcessing(67); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadCaddyConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); sshShellCommand = @"mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (String.Equals( ReceiveConfigurationParameters[0], "ObfsPluginHttpWebSS") == true) { @@ -8705,295 +4681,53 @@ namespace ProxySU string randomCaddyListenPortStr = randomCaddyListenPort.ToString(); sshShellCommand = $"sed -i 's/8800/{randomCaddyListenPortStr}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //设置域名 sshShellCommand = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/g' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //设置Path sshShellCommand = $"sed -i 's/##path##/\\{ReceiveConfigurationParameters[3]}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //设置伪装网站 if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) { sshShellCommand = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); } //****** "Caddy配置文件上传成功,OK!" ****** - SetUpProgressBarProcessing(85); + SetUpProgressBarProcessing(70); currentStatus = Application.Current.FindResource("DisplayInstallInfo_UploadCaddyConfigOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); - //Thread.Sleep(1000); - - //****** "正在启动Caddy......" ****** - SetUpProgressBarProcessing(87); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyService").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //启动Caddy服务 - sshShellCommand = @"systemctl restart caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) - { - //****** "Caddy启动成功!" ****** - SetUpProgressBarProcessing(88); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Caddy启动失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - - //****** "正在启动Caddy(第二次尝试)!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceSecond").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(3000); - sshShellCommand = @"systemctl restart caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) - { - //****** "Caddy启动成功!" ****** - SetUpProgressBarProcessing(88); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "Caddy启动失败(第二次)!退出安装!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartCaddyServiceSecondFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - //****** "Caddy启动失败,原因未知!请向开发者问询!" ****** - MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_CaddyServiceFailedExit").ToString()); - return; - } - } + //程序启动检测Caddy + functionResult = SoftStartDetect(client, "caddy", @"/usr/bin/caddy"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } } - //****** "正在启动SS......" ****** - SetUpProgressBarProcessing(90); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartSoft").ToString() + "SS......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //程序启动检测SS + functionResult = SoftStartDetect(client, "ss-server", @"/usr/local/bin/ss-server"); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - //Thread.Sleep(1000); - //启动SS服务 - sshShellCommand = @"systemctl restart ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测BBR,满足条件并启动 90--95 + functionResult = DetectBBRandEnable(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - if (currentShellCommandResult.Contains("/usr/local/bin/ss-server") == true) - { - //****** "SS启动成功!" ****** - SetUpProgressBarProcessing(93); - currentStatus = "SS" + Application.Current.FindResource("DisplayInstallInfo_StartSoftOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "SS启动失败!" ****** - currentStatus = "SS" + Application.Current.FindResource("DisplayInstallInfo_StartSoftFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(3000); - //****** "正在第二次尝试启动SS!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartSoftSecond").ToString() + "SS!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - Thread.Sleep(3000); - sshShellCommand = @"systemctl restart ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - Thread.Sleep(3000); - - sshShellCommand = @"ps aux | grep ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - if (currentShellCommandResult.Contains("/usr/local/bin/ss-server") == true) - { - //****** "SS启动成功!" ****** - SetUpProgressBarProcessing(93); - currentStatus = "SS" + Application.Current.FindResource("DisplayInstallInfo_StartSoftOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - } - else - { - //****** "SS启动失败(第二次)!退出安装!" ****** - currentStatus = "SS" + Application.Current.FindResource("DisplayInstallInfo_StartSoftSecondFail").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); - //****** "SS启动失败,原因未知!请向开发者问询!" ****** - MessageBox.Show("SS" + Application.Current.FindResource("DisplayInstallInfo_StartSoftFailedExit").ToString()); - return; - } - } - - - //测试BBR条件,若满足提示是否启用 - //****** "BBR测试......" ****** - SetUpProgressBarProcessing(95); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - sshShellCommand = @"uname -r"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - string[] linuxKernelVerStrBBR = currentShellCommandResult.Split('-'); - - bool detectResultBBR = DetectKernelVersionBBR(linuxKernelVerStrBBR[0]); - - 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 (detectResultBBR == true && resultCmdTestBBR.Contains("bbr") == false) - { - //****** "正在启用BBR......" ****** - SetUpProgressBarProcessing(97); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); - - 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) - { - //****** "BBR已经启用了!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRisEnabled").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } - else - { - //****** "系统不满足启用BBR的条件,启用失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } + client.Disconnect();//断开服务器ssh连接 //****** "生成客户端配置......" ****** - SetUpProgressBarProcessing(99); + SetUpProgressBarProcessing(96); currentStatus = Application.Current.FindResource("DisplayInstallInfo_GenerateClientConfig").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //****** "SS安装成功,祝你玩的愉快!!" ****** SetUpProgressBarProcessing(100); currentStatus = "SS" + Application.Current.FindResource("DisplayInstallInfo_ProxyInstalledOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); //显示服务端连接参数 proxyType = "SS"; @@ -9061,13 +4795,13 @@ namespace ProxySU } installationDegree = 0; TextBoxMonitorCommandResults.Text = ""; - Thread thread = new Thread(() => StartSetUpMtg(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + Thread thread = new Thread(() => StartSetUpMtg(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //Mtg安装进程 - private void StartSetUpMtg(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void StartSetUpMtg(ConnectionInfo connectionInfo) { functionResult = true; getApt = false; @@ -9234,7 +4968,7 @@ namespace ProxySU currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartInstallSoft").ToString() + "MTProto......"; MainWindowsShowInfo(currentStatus); - sshShellCommand = @"curl -o /tmp/mtg_install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/MTProto/mtg_install.sh"; + sshShellCommand = $"curl -o /tmp/mtg_install.sh https://{scriptGithubUrl}/proxysu/shellscript/master/MTProto/mtg_install.sh"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = $"yes | bash /tmp/mtg_install.sh {ReceiveConfigurationParameters[1]} {ReceiveConfigurationParameters[7]}"; @@ -9305,7 +5039,7 @@ namespace ProxySU } } - //检测系统内核是否符合安装要求 + #region 检测系统内核是否符合安装要求 //private static bool DetectKernelVersion(string kernelVer) //{ // string[] linuxKernelCompared = kernelVer.Split('.'); @@ -9349,7 +5083,7 @@ namespace ProxySU // return false; //} - + #endregion //打开系统工具中的校对时间窗口 private void ButtonProofreadTime_Click(object sender, RoutedEventArgs e) @@ -9439,19 +5173,24 @@ namespace ProxySU return; } - Thread thread = new Thread(() => StartTestAndEnableBBR(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + installationDegree = 0; + TextBoxMonitorCommandResults.Text = ""; + Thread thread = new Thread(() => StartTestAndEnableBBR(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } //启用BBR的主要进程 - private void StartTestAndEnableBBR(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void StartTestAndEnableBBR(ConnectionInfo connectionInfo) { + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; + //******"正在登录远程主机......"****** - string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); + MainWindowsShowInfo(currentStatus); try { @@ -9490,106 +5229,54 @@ namespace ProxySU { //******"主机登录成功"****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } - //******"检测是否运行在root权限下..."****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - 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) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } //****** "BBR测试......" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); sshShellCommand = @"uname -r"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string[] linuxKernelVerStrBBR = currentShellCommandResult.Split('-'); bool detectResultBBR = DetectKernelVersionBBR(linuxKernelVerStrBBR[0]); 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);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); string resultCmdTestBBR = currentShellCommandResult; //如果内核满足大于等于4.9,且还未启用BBR,则启用BBR if (detectResultBBR == true && resultCmdTestBBR.Contains("bbr") == false) { //****** "正在启用BBR......" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_EnableBBR").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); 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);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); 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);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"sysctl -p"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); } else if (resultCmdTestBBR.Contains("bbr") == true) { //****** "BBR已经启用了!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRisEnabled").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //****** "系统不满足启用BBR的条件,启用失败!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_BBRFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } client.Disconnect();//断开服务器ssh连接 @@ -9603,10 +5290,7 @@ namespace ProxySU //****** "主机登录失败!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -9657,21 +5341,26 @@ namespace ProxySU return; } - Thread thread = new Thread(() => StartRemoveProxySoft(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing)); + installationDegree = 0; + TextBoxMonitorCommandResults.Text = ""; + Thread thread = new Thread(() => StartRemoveProxySoft(connectionInfo)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } } //卸载代理进程 - private void StartRemoveProxySoft(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar) + private void StartRemoveProxySoft(ConnectionInfo connectionInfo) { + functionResult = true; + getApt = false; + getDnf = false; + getYum = false; + //******"正在登录远程主机......"****** SetUpProgressBarProcessing(1); string currentStatus = Application.Current.FindResource("DisplayInstallInfo_Login").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); try { @@ -9711,64 +5400,29 @@ namespace ProxySU //******"主机登录成功"****** SetUpProgressBarProcessing(5); currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginSuccessful").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果在监视窗口 - //Thread.Sleep(1000); + MainWindowsShowInfo(currentStatus); } - //******"检测是否运行在root权限下..."****** - SetUpProgressBarProcessing(6); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootPermission").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + //检测root权限 5--7 + functionResult = RootAuthorityDetect(client); + if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } - 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) - { - //******"请使用具有root权限的账户登录主机!!"****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorRootPermission").ToString()); - client.Disconnect(); - return; - } - else - { - //******"检测结果:OK!"****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DetectionRootOK").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - } //******"开始卸载......"****** SetUpProgressBarProcessing(10); currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() + "......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); #region 卸载V2Ray //******"检测系统是否已经安装V2ray......"******03 SetUpProgressBarProcessing(11); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "V2ray......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"find / -name v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //string resultCmdTestV2rayInstalled = currentShellCommandResult; if (currentShellCommandResult.Contains("/usr/local/bin/v2ray") == true) { //******"检测到已安装V2Ray!开始卸载V2Ray......"****** @@ -9777,64 +5431,41 @@ namespace ProxySU + "V2Ray!" + Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() + "V2Ray......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"systemctl stop v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - - sshShellCommand = @"curl -LROJ https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -LROJ https://{scriptGithubUrl}/v2fly/fhs-install-v2ray/master/install-release.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash install-release.sh --remove"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"systemctl disable v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -rf /usr/local/etc/v2ray /var/log/v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f install-release.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"find / -name v2ray"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("/usr/local/bin/v2ray") == true) { //******"V2Ray卸载失败!请向开发者问询!"****** currentStatus = "V2Ray" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //******"V2Ray卸载成功!"****** SetUpProgressBarProcessing(16); currentStatus ="V2Ray" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } } @@ -9843,10 +5474,7 @@ namespace ProxySU //******"检测结果:未安装V2Ray!"******04 SetUpProgressBarProcessing(16); currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "V2Ray!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -9856,16 +5484,11 @@ namespace ProxySU //******"检测系统是否已经安装Trojan-go......"******03 SetUpProgressBarProcessing(17); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "Trojan-go......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"find / -name trojan-go"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //string resultCmdTestV2rayInstalled = currentShellCommandResult; if (currentShellCommandResult.Contains("/usr/local/bin/trojan-go") == true) { //******"检测到已安装Trojan-go,开始卸载Trojan-go......"****** @@ -9873,64 +5496,42 @@ namespace ProxySU currentStatus = Application.Current.FindResource("DisplayInstallInfo_DiscoverProxySoft").ToString() + "Trojan-go!" + Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() - + "Trojan-go......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + + "Trojan-go......"; + MainWindowsShowInfo(currentStatus); sshShellCommand = @"systemctl stop trojan-go"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - - sshShellCommand = @"curl -LROJ https://raw.githubusercontent.com/proxysu/shellscript/master/trojan-go.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -LROJ https://{scriptGithubUrl}/proxysu/shellscript/master/trojan-go.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash trojan-go.sh --remove"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"systemctl disable trojan-go"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -rf /usr/local/etc/trojan-go /var/log/trojan-go"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f trojan-go.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"find / -name trojan-go"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("/usr/local/bin/trojan-go") == true) { //******"Trojan-go卸载失败!请向开发者问询!"****** currentStatus = "Trojan-go" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //******"Trojan-go卸载成功!"****** SetUpProgressBarProcessing(22); currentStatus = "Trojan-go" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } } @@ -9939,10 +5540,7 @@ namespace ProxySU //******"检测结果:未安装Trojan-go!"******04 SetUpProgressBarProcessing(22); currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "Trojan-go!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -9952,16 +5550,11 @@ namespace ProxySU //******"检测系统是否已经安装Trojan......"******03 SetUpProgressBarProcessing(23); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "Trojan......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"find / -name trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //string resultCmdTestV2rayInstalled = currentShellCommandResult; if (currentShellCommandResult.Contains("/usr/local/bin/trojan") == true) { //******"检测到已安装Trojan,开始卸载Trojan......"****** @@ -9970,48 +5563,32 @@ namespace ProxySU + "Trojan!" + Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() + "Trojan......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"systemctl stop trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"systemctl disable trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -rf /usr/local/bin/trojan /etc/systemd/system/trojan.service /usr/local/etc/trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"find / -name trojan"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("/usr/local/bin/trojan") == true) { //******"Trojan卸载失败!请向开发者问询!"****** currentStatus = "Trojan" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //******"Trojan卸载成功!"****** SetUpProgressBarProcessing(30); currentStatus = "Trojan" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } } @@ -10020,10 +5597,7 @@ namespace ProxySU //******"检测结果:未安装Trojan!"******04 SetUpProgressBarProcessing(30); currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "Trojan!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -10033,16 +5607,11 @@ namespace ProxySU //******"检测系统是否已经安装SSR......"******03 SetUpProgressBarProcessing(31); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "SSR......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"if [ -f /usr/local/shadowsocks/server.py ];then echo '1';else echo '0'; fi"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //string resultCmdTestV2rayInstalled = currentShellCommandResult; if (currentShellCommandResult.Contains("1") == true) { //******"检测到已安装SSR,开始卸载SSR......"****** @@ -10051,59 +5620,38 @@ namespace ProxySU + "SSR!" + Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() + "SSR......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"systemctl stop ssr"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - - sshShellCommand = @"curl -LROJ https://raw.githubusercontent.com/proxysu/shellscript/master/ssr/ssr.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -LROJ https://{scriptGithubUrl}/proxysu/shellscript/master/ssr/ssr.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash ssr.sh uninstall"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"systemctl disable ssr"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f ssr.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"if [ -f /usr/local/shadowsocks/server.py ];then echo '1';else echo '0'; fi"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("1") == true) { //******"SSR卸载失败!请向开发者问询!"****** currentStatus = "SSR" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //******"SSR卸载成功!"****** SetUpProgressBarProcessing(36); currentStatus = "SSR" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } } @@ -10112,10 +5660,7 @@ namespace ProxySU //******"检测结果:未安装SSR!"******04 SetUpProgressBarProcessing(36); currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "SSR!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -10125,16 +5670,11 @@ namespace ProxySU //******"检测系统是否已经安装SS (Shadowsoks-libev)......"******03 SetUpProgressBarProcessing(37); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "SS (Shadowsoks-libev)......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"find / -name ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //string resultCmdTestV2rayInstalled = currentShellCommandResult; if (currentShellCommandResult.Contains("/usr/local/bin/ss-server") == true) { //******"检测到SS(Shadowsoks-libev),开始卸载SS(Shadowsoks-libev)......"****** @@ -10143,66 +5683,42 @@ namespace ProxySU + "SS (Shadowsoks-libev)!" + Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() + "SS (Shadowsoks-libev)......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"systemctl stop ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - - sshShellCommand = @"curl -LROJ https://raw.githubusercontent.com/proxysu/shellscript/master/ss/ss-install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + sshShellCommand = $"curl -LROJ https://{scriptGithubUrl}/proxysu/shellscript/master/ss/ss-install.sh"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"bash ss-install.sh uninstall"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"systemctl disable ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -f ss-install.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //卸载插件 sshShellCommand = @"rm -f /usr/local/bin/obfs-server /usr/local/bin/obfs-local /usr/local/bin/v2ray-plugin /usr/local/bin/kcptun-plugin-server /usr/local/bin/goquiet-plugin-server /usr/local/bin/cloak-plugin-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"find / -name ss-server"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("/usr/local/bin/ss-server") == true) { //******"SS(Shadowsoks-libev)卸载失败!请向开发者问询!"****** currentStatus = "SS (Shadowsoks-libev)" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //******"SS (Shadowsoks-libev)卸载成功!"****** SetUpProgressBarProcessing(46); currentStatus = "SS (Shadowsoks-libev)" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } } @@ -10211,10 +5727,7 @@ namespace ProxySU //******"检测结果:未安装SS(Shadowsoks-libev)!"******04 SetUpProgressBarProcessing(47); currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "SS (Shadowsoks-libev)!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } @@ -10225,16 +5738,11 @@ namespace ProxySU //******"检测系统是否已经安装acme.sh......"******03 SetUpProgressBarProcessing(48); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "acme.sh......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"if [ -d ~/.acme.sh ];then echo '1';else echo '0'; fi"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //string resultCmdTestV2rayInstalled = currentShellCommandResult; if (currentShellCommandResult.Contains("1") == true) { //******"检测到acme.sh,开始卸载acme.sh......"****** @@ -10243,43 +5751,29 @@ namespace ProxySU + "acme.sh!" + Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() + "acme.sh......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"acme.sh --uninstall"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -r ~/.acme.sh"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"if [ -d ~/.acme.sh ];then echo '1';else echo '0'; fi"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("1") == true) { //******"acme.sh卸载失败!请向开发者问询!"****** currentStatus = "acme.sh" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //******"acme.sh卸载成功!"****** SetUpProgressBarProcessing(46); currentStatus = "acme.sh" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } } @@ -10288,10 +5782,7 @@ namespace ProxySU //******"检测结果:未安装acme.sh!"******04 SetUpProgressBarProcessing(46); currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "acme.sh!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -10301,16 +5792,11 @@ namespace ProxySU //******"检测系统是否已经安装Caddy/NaiveProxy......"******03 SetUpProgressBarProcessing(48); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "Caddy/NaiveProxy......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"find / -name caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //string resultCmdTestV2rayInstalled = currentShellCommandResult; if (currentShellCommandResult.Contains("/usr/bin/caddy") == true) { //******"检测到Caddy/NaiveProxy,开始卸载Caddy/NaiveProxy......"****** @@ -10319,90 +5805,36 @@ namespace ProxySU + "Caddy/NaiveProxy!" + Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() + "Caddy/NaiveProxy......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"systemctl stop caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"systemctl disable caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); //检测系统是否支持yum 或 apt或zypper //如果不存在组件,则命令结果为空,string.IsNullOrEmpty值为真, sshShellCommand = @"command -v apt"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); 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);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); 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);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); bool getYum = ! String.IsNullOrEmpty(currentShellCommandResult); SetUpProgressBarProcessing(55); sshShellCommand = @"command -v zypper"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); bool getZypper = String.IsNullOrEmpty(currentShellCommandResult); - //sshShellCommand = @"command -v systemctl"; - //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - //currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - //bool getSystemd = String.IsNullOrEmpty(currentShellCommandResult); - - //sshShellCommand = @"command -v getenforce"; - //TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - //currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - - //bool getGetenforce = String.IsNullOrEmpty(currentShellCommandResult); - - - //没有安装apt,也没有安装dnf\yum,也没有安装zypper,或者没有安装systemd的,不满足安装条件 - //也就是apt ,dnf\yum, zypper必须安装其中之一,且必须安装Systemd的系统才能安装。 - //if ((getApt && getDnf && getYum && getZypper)) - //{ - // //******"系统缺乏必要的安装组件如:apt||dnf||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本"****** - // MessageBox.Show(Application.Current.FindResource("MessageBoxShow_MissingSystemComponents").ToString()); - - // //******"系统环境不满足要求,安装失败!!"****** - // currentStatus = Application.Current.FindResource("DisplayInstallInfo_MissingSystemComponents").ToString(); - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // currentShellCommandResult = currentStatus; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - // //Thread.Sleep(1000); - // client.Disconnect(); - // return; - //} - //else - //{ - // //******"检测结果:OK!"******06 - // SetUpProgressBarProcessing(57); - // currentStatus = Application.Current.FindResource("DisplayInstallInfo_SystemRequirementsOK").ToString(); - // textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - // currentShellCommandResult = currentStatus; - // TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - - //} - string sshCmdRemove = ""; //string sshCmdRemove2; //设置安装软件所用的命令格式 @@ -10428,33 +5860,23 @@ namespace ProxySU } sshShellCommand = $"{sshCmdRemove}caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"find / -name caddy"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("/usr/local/bin/caddy") == true) { //******"Caddy/NaiveProxy卸载失败!请向开发者问询!"****** currentStatus = "Caddy/NaiveProxy" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //******"Caddy/NaiveProxy卸载成功!"****** SetUpProgressBarProcessing(60); currentStatus = "Caddy/NaiveProxy" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } } @@ -10463,10 +5885,7 @@ namespace ProxySU //******"检测结果:未安装Caddy/NaiveProxy!"******04 SetUpProgressBarProcessing(60); currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "Caddy/NaiveProxy!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion @@ -10475,16 +5894,11 @@ namespace ProxySU //******"检测系统是否已经安装MtProto......"******03 SetUpProgressBarProcessing(61); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestExistSoft").ToString() + "MtProto......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"find / -name mtg"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - //string resultCmdTestV2rayInstalled = currentShellCommandResult; if (currentShellCommandResult.Contains("/usr/local/bin/mtg") == true) { //******"检测到MtProto,开始卸载MtProto......"****** @@ -10493,59 +5907,38 @@ namespace ProxySU + "MtProto!" + Application.Current.FindResource("DisplayInstallInfo_StartRemoveProxy").ToString() + "MtProto......"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + MainWindowsShowInfo(currentStatus); sshShellCommand = @"systemctl stop mtg"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"systemctl disable mtg"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -rf /etc/systemd/system/mtg.service"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -rf /usr/local/bin/mtg"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"rm -rf /usr/local/etc/mtg_info.json"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); sshShellCommand = @"find / -name mtg"; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, sshShellCommand);//显示执行的命令 - currentShellCommandResult = client.RunCommand(sshShellCommand).Result; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("/usr/local/bin/mtg") == true) { //******"MtProto卸载失败!请向开发者问询!"****** currentStatus = "MtProto" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } else { //******"MtProto卸载成功!"****** SetUpProgressBarProcessing(65); currentStatus = "MtProto" + Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } } @@ -10554,20 +5947,14 @@ namespace ProxySU //******"检测结果:未安装MtProto!"******04 SetUpProgressBarProcessing(65); currentStatus = Application.Current.FindResource("DisplayInstallInfo_NoInstalledSoft").ToString() + "MtProto!"; - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion //******"卸载成功!"******04 SetUpProgressBarProcessing(100); currentStatus = Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); client.Disconnect(); MessageBox.Show(Application.Current.FindResource("DisplayInstallInfo_RemoveProxySoftSuccess").ToString()); @@ -10582,17 +5969,12 @@ namespace ProxySU //****** "主机登录失败!" ****** currentStatus = Application.Current.FindResource("DisplayInstallInfo_LoginFailed").ToString(); - textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - currentShellCommandResult = currentStatus; - TextBoxMonitorCommandResults.Dispatcher.BeginInvoke(updateMonitorAction, TextBoxMonitorCommandResults, currentShellCommandResult);//显示命令执行的结果 - + MainWindowsShowInfo(currentStatus); } #endregion } - - #endregion #region 资源工具标签页控制 @@ -11011,7 +6393,7 @@ namespace ProxySU // Thread.Sleep(1000); // //下载官方安装脚本安装V2ray - // client.RunCommand("curl -o /tmp/go.sh https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh"); + // client.RunCommand($"curl -o /tmp/go.sh https://{scriptGithubUrl}/v2fly/fhs-install-v2ray/master/install-release.sh"); // client.RunCommand("yes | bash /tmp/go.sh -f"); // string installResult = client.RunCommand("find / -name v2ray").Result.ToString(); @@ -11062,7 +6444,7 @@ namespace ProxySU // //下载官方安装脚本安装 - // client.RunCommand("curl -o /tmp/trojan-quickstart.sh https://raw.githubusercontent.com/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"); + // client.RunCommand($"curl -o /tmp/trojan-quickstart.sh https://{scriptGithubUrl}/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh"); // client.RunCommand("yes | bash /tmp/trojan-quickstart.sh"); // installResult = client.RunCommand("find / -name trojan").Result.ToString(); @@ -11108,7 +6490,7 @@ namespace ProxySU // //下载安装脚本安装 - // client.RunCommand("curl -o /tmp/naive-quickstart.sh https://raw.githubusercontent.com/proxysu/shellscript/master/naive-quickstart.sh"); + // client.RunCommand($"curl -o /tmp/naive-quickstart.sh https://{scriptGithubUrl}/proxysu/shellscript/master/naive-quickstart.sh"); // client.RunCommand("yes | bash /tmp/naive-quickstart.sh"); // installResult = client.RunCommand("find / -name naive").Result.ToString(); @@ -11154,7 +6536,7 @@ namespace ProxySU // // client.RunCommand("zypper ref"); // client.RunCommand("zypper -y install socat"); // } - // client.RunCommand("curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"); + // client.RunCommand($"curl https://{scriptGithubUrl}/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"); // client.RunCommand("cd ~/.acme.sh/"); // client.RunCommand("alias acme.sh=~/.acme.sh/acme.sh"); @@ -11679,7 +7061,7 @@ namespace ProxySU MainWindowsShowInfo(currentStatus); sshShellCommand = @"id -u"; - MainWindowsShowCmd(client, sshShellCommand); + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); client.Disconnect(); } @@ -11726,12 +7108,6 @@ namespace ProxySU } #endregion - //TextBoxMonitorCommandResults.Text = ""; - //functionResult = true; - //getApt = false; - //getDnf = false; - //getYum = false; - //检测root权限 5--7 //functionResult = RootAuthorityDetect(client); //if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } @@ -11879,6 +7255,33 @@ namespace ProxySU MainWindowsShowInfo(currentStatus); } + //检测是否安装dig + if (string.IsNullOrEmpty(client.RunCommand("command -v dig").Result) == true) + { + //设置安装软件所用的命令格式 + if (getApt == true) + { + sshCmdUpdate = @"apt -qq update"; + sshCmdInstall = @"apt -y -qq install dnsutils"; + } + else if (getDnf == true) + { + sshCmdUpdate = @"dnf -q makecache"; + sshCmdInstall = @"dnf -y -q install bind-utils"; + } + else if (getYum == true) + { + sshCmdUpdate = @"yum -q makecache"; + sshCmdInstall = @"yum -y -q install bind-utils"; + } + sshShellCommand = sshCmdUpdate; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + + sshShellCommand = sshCmdInstall; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + + } + //设置安装软件所用的命令格式 if (getApt == true) { @@ -11959,6 +7362,16 @@ namespace ProxySU sshShellCommand = $"{sshCmdInstall}unzip"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + } + //处理极其少见的xz-utils未安装的情况 + if (string.IsNullOrEmpty(client.RunCommand("command -v xz-utils").Result) == true) + { + sshShellCommand = $"{sshCmdUpdate}"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + + sshShellCommand = $"{sshCmdInstall}xz-utils"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + } //检测是否安装lsof if (string.IsNullOrEmpty(client.RunCommand("command -v lsof").Result) == true) @@ -11970,6 +7383,9 @@ namespace ProxySU currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); } + + + //****** "检测端口占用情况......" ****** SetUpProgressBarProcessing(22); currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestPortUsed").ToString(); @@ -12213,33 +7629,100 @@ namespace ProxySU currentStatus = Application.Current.FindResource("DisplayInstallInfo_TestDomainResolve").ToString(); MainWindowsShowInfo(currentStatus); - sshShellCommand = @"curl -4 ip.sb"; + //再次初始化相关变量 + ipv4 = String.Empty; + ipv6 = String.Empty; + onlyIpv6 = false; + + //sshShellCommand = @"curl -4 ip.sb"; + sshShellCommand = @"curl -s https://api.ip.sb/ip --ipv4"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + ipv4 = currentShellCommandResult.TrimEnd('\r', '\n'); - string nativeIp = currentShellCommandResult; - - sshShellCommand = "ping " + ReceiveConfigurationParameters[4] + " -c1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; + sshShellCommand = @"curl -s https://api.ip.sb/ip --ipv6"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + ipv6 = currentShellCommandResult.TrimEnd('\r', '\n'); - string resultTestDomainCmd = currentShellCommandResult; - if (String.Equals(nativeIp, resultTestDomainCmd) == true) + if (String.IsNullOrEmpty(ipv4) == false) { - //****** "解析正确!OK!" ******12 - SetUpProgressBarProcessing(36); - currentStatus = Application.Current.FindResource("DisplayInstallInfo_DomainResolveOK").ToString(); - MainWindowsShowInfo(currentStatus); + string nativeIp = ipv4; + + sshShellCommand = "ping " + ReceiveConfigurationParameters[4] + " -c1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + + string resultTestDomainCmd = currentShellCommandResult.TrimEnd('\r', '\n'); + if (String.Equals(nativeIp, resultTestDomainCmd) == true) + { + //****** "解析正确!OK!" ******12 + SetUpProgressBarProcessing(36); + currentStatus = Application.Current.FindResource("DisplayInstallInfo_DomainResolveOK").ToString(); + MainWindowsShowInfo(currentStatus); + onlyIpv6 = false; + return true; + } + else + { + //****** "域名未能正确解析到当前VPS的IP上!安装失败!" ****** + currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorDomainResolve").ToString(); + MainWindowsShowInfo(currentStatus); + + //****** "域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!" ****** + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorDomainResolve").ToString()); + //client.Disconnect(); + return false; + } } else { - //****** "域名未能正确解析到当前VPS的IP上!安装失败!" ****** - currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorDomainResolve").ToString(); - MainWindowsShowInfo(currentStatus); + if (String.IsNullOrEmpty(ipv6) == false) + { + string nativeIp = ipv6; - //****** "域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!" ****** - MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorDomainResolve").ToString()); - //client.Disconnect(); - return false; + //sshShellCommand = "ping6 " + ReceiveConfigurationParameters[4] + " -c1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; + sshShellCommand = $"dig @resolver1.opendns.com AAAA {ReceiveConfigurationParameters[4]} +short -6"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + + string resultTestDomainCmd = currentShellCommandResult.TrimEnd('\r', '\n'); + if (String.Equals(nativeIp, resultTestDomainCmd) == true) + { + //****** "解析正确!OK!" ******12 + SetUpProgressBarProcessing(36); + currentStatus = Application.Current.FindResource("DisplayInstallInfo_DomainResolveOK").ToString(); + MainWindowsShowInfo(currentStatus); + scriptGithubUrl = "ipv6.githubipv6.ga"; + onlyIpv6 = true; + //纯ipv6主机,目前暂不支持 + currentStatus = Application.Current.FindResource("DisplayInstallInfo_OnlyIpv6").ToString(); + MainWindowsShowInfo(currentStatus); + MessageBox.Show(currentStatus); + return false; + } + else + { + //****** "域名未能正确解析到当前VPS的IP上!安装失败!" ****** + currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorDomainResolve").ToString(); + MainWindowsShowInfo(currentStatus); + + //****** "域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!" ****** + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorDomainResolve").ToString()); + //client.Disconnect(); + return false; + } + + } + else + { + //****** "域名未能正确解析到当前VPS的IP上!安装失败!" ****** + currentStatus = Application.Current.FindResource("DisplayInstallInfo_ErrorDomainResolve").ToString(); + MainWindowsShowInfo(currentStatus); + + //****** "域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!" ****** + MessageBox.Show(Application.Current.FindResource("MessageBoxShow_ErrorDomainResolve").ToString()); + //client.Disconnect(); + return false; + } } + return true; } @@ -12317,7 +7800,7 @@ namespace ProxySU sshShellCommand = $"{sshCmdInstall}automake autoconf libtool"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); - sshShellCommand = @"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"; + sshShellCommand = $"curl https://{scriptGithubUrl}/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"; currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); if (currentShellCommandResult.Contains("Install success") == true) @@ -12346,8 +7829,16 @@ namespace ProxySU currentStatus = Application.Current.FindResource("DisplayInstallInfo_StartApplyCert").ToString(); MainWindowsShowInfo(currentStatus); - sshShellCommand = $"/root/.acme.sh/acme.sh --force --issue --standalone -d {ReceiveConfigurationParameters[4]}"; - currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + if (onlyIpv6 == true) + { + sshShellCommand = $"/root/.acme.sh/acme.sh --force --issue --standalone -d {ReceiveConfigurationParameters[4]} --listen-v6"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + } + else + { + sshShellCommand = $"/root/.acme.sh/acme.sh --force --issue --standalone -d {ReceiveConfigurationParameters[4]}"; + currentShellCommandResult = MainWindowsShowCmd(client, sshShellCommand); + } if (currentShellCommandResult.Contains("Cert success") == true) { @@ -12373,7 +7864,7 @@ namespace ProxySU - //Caddy安装 61--66 + //Caddy安装与检测安装是否成功 61--66 //functionResult = CaddyInstall(client); //if (functionResult == false) { FunctionResultErr(); client.Disconnect(); return; } private bool CaddyInstall(SshClient client) diff --git a/ProxySU/Properties/AssemblyInfo.cs b/ProxySU/Properties/AssemblyInfo.cs index a066fd9..256e4d3 100644 --- a/ProxySU/Properties/AssemblyInfo.cs +++ b/ProxySU/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ using System.Windows; // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.4.5.0")] -[assembly: AssemblyFileVersion("2.4.5.0")] +[assembly: AssemblyVersion("2.4.6.0")] +[assembly: AssemblyFileVersion("2.4.6.0")] diff --git a/ProxySU/Translations/ProxySU.en-US.xaml b/ProxySU/Translations/ProxySU.en-US.xaml index fac7b85..e11450e 100644 --- a/ProxySU/Translations/ProxySU.en-US.xaml +++ b/ProxySU/Translations/ProxySU.en-US.xaml @@ -260,6 +260,7 @@ The time difference meets the requirements, OK! is checking whether the domain name is resolved to the IP of the current VPS... The resolution is correct! OK! + detects that the current host is a pure ipv6 host, it is not currently supported! The domain name could not be correctly resolved to the IP of the current VPS! Installation failed! The domain name cannot be correctly resolved to the IP of the current VPS, please check! If the resolution setting is correct, please wait for it to take effect before retrying the installation. If the domain name uses CDN, please close it first! Detect port occupancy... diff --git a/ProxySU/Translations/ProxySU.zh-CN.xaml b/ProxySU/Translations/ProxySU.zh-CN.xaml index e27655f..e77b41f 100644 --- a/ProxySU/Translations/ProxySU.zh-CN.xaml +++ b/ProxySU/Translations/ProxySU.zh-CN.xaml @@ -269,6 +269,7 @@ 时间差符合要求,OK! 正在检测域名是否解析到当前VPS的IP上...... 解析正确!OK! + 检测当前主机为纯ipv6主机,目前暂不支持! 域名未能正确解析到当前VPS的IP上!安装失败! 域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭! 检测端口占用情况...... diff --git a/ProxySU/Translations/ProxySU.zh-TW.xaml b/ProxySU/Translations/ProxySU.zh-TW.xaml index 2f1ec92..4a7bc38 100644 --- a/ProxySU/Translations/ProxySU.zh-TW.xaml +++ b/ProxySU/Translations/ProxySU.zh-TW.xaml @@ -262,6 +262,7 @@ 時間差符合要求,OK! 正在檢測域名是否解析到當前VPS的IP上...... 解析正確! OK! + 檢測當前主機為純ipv6主機,目前暫不支持! 域名未能正確解析到當前VPS的IP上!安裝失敗! 域名未能正確解析到當前VPS的IP上,請檢查!若解析設置正確,請等待生效後再重試安裝。如果域名使用了CDN,請先關閉! 檢測端口占用情況...... diff --git a/ProxySU/bin/Beta/Beta.zip b/ProxySU/bin/Beta/Beta.zip index 7d191ba01b07a54b52219e7e2dc1b603ba11c2af..312cb5f3c2200c5a3b9d5621cf8fe9a465addc91 100644 GIT binary patch delta 118816 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 delta 122713 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