From d30bef19e7ccc32d85697d124b66732898971d5f Mon Sep 17 00:00:00 2001 From: bicijinlian Date: Sat, 29 Jun 2024 15:43:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(all):=E6=95=B4=E7=90=86=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/1.1.概述.ipynb | 5 - Docs/1.2.使用准则.ipynb | 105 ++++++-- Docs/1.3.0.基础使用.管理客户端.ipynb | 24 +- HttpClientStudy.Core/Utilities/AppUtility.cs | 232 +++++++++++++++++- .../Utilities/DotnetCommondUtility.cs | 188 -------------- .../Utilities/StartupUtility.cs | 112 --------- .../UtilitiesTest/AppUtilityTest.cs | 9 + .../UtilitiesTest/DotnetCommondUtilityTest.cs | 43 ---- HttpClientStudy.UnitTest/startup.cs | 2 +- .../Controllers/ManagerController.cs | 4 +- HttpClientStudy.WebClient/Program.cs | 4 +- 11 files changed, 340 insertions(+), 388 deletions(-) delete mode 100644 HttpClientStudy.Core/Utilities/DotnetCommondUtility.cs delete mode 100644 HttpClientStudy.Core/Utilities/StartupUtility.cs delete mode 100644 HttpClientStudy.UnitTest/UtilitiesTest/DotnetCommondUtilityTest.cs diff --git a/Docs/1.1.概述.ipynb b/Docs/1.1.概述.ipynb index c7c74ff..e7fe202 100644 --- a/Docs/1.1.概述.ipynb +++ b/Docs/1.1.概述.ipynb @@ -134,11 +134,6 @@ "\n", "后续将从基础使用到高级使用,一步步展开,一步步学习。" ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] } ], "metadata": { diff --git a/Docs/1.2.使用准则.ipynb b/Docs/1.2.使用准则.ipynb index 22d9485..14e92d9 100644 --- a/Docs/1.2.使用准则.ipynb +++ b/Docs/1.2.使用准则.ipynb @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -42,6 +42,7 @@ "source": [ "//全局设置\n", "#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n", + "\n", "global using System.Net;\n", "global using System.Net.Http;\n", "global using System.Diagnostics;\n", @@ -73,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -85,15 +86,7 @@ "languageId": "polyglot-notebook" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "soft.pwidc.cn\r\n" - ] - } - ], + "outputs": [], "source": [ "{ //大括号: 1、作用域隔离 2、方便整体代码折叠\n", " Console.WriteLine(global_queryDomain);\n", @@ -109,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "pwsh" @@ -402,7 +395,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -414,7 +407,22 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "47.103.77.66\n", + "程序运行大约要10-20,请在程序退出后,执行下面命令行查看网络情况\n", + " TCP 192.168.1.151:14073 47.103.77.66:80 TIME_WAIT 0\n", + " TCP 192.168.1.151:14079 47.103.77.66:80 TIME_WAIT 0\n", + " TCP 192.168.1.151:14085 47.103.77.66:80 TIME_WAIT 0\n", + " TCP 192.168.1.151:14092 47.103.77.66:80 TIME_WAIT 0\n", + " TCP 192.168.1.151:14101 47.103.77.66:80 ESTABLISHED 39888\n", + "\n" + ] + } + ], "source": [ "{ //\n", " var ips = await Dns.GetHostAddressesAsync(global_queryDomain);\n", @@ -506,7 +514,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -518,7 +526,20 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "开始请求网络...\n", + "共请求了200次,耗时 24989 毫秒\n", + "当前网络状态\n", + " TCP 192.168.1.151:18018 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18019 47.103.77.66:80 ESTABLISHED 32156\n", + "\n" + ] + } + ], "source": [ "/*\n", "\t功能:将MaxConnectionsPerServer限制为2。然后启动200个任务,每个任务都向同一端点发出HTTP请求。这些任务将同时运行。所有请求竞争所花费的时间将写入控制台。\n", @@ -547,14 +568,14 @@ "\t\t\n", "\t//执行查看网络状态方法\n", "\tConsole.WriteLine(\"当前网络状态\");\n", - "\tvar message = HttpClientStudy.Core.Utilities.CmdUtility.RunCmd($\"netstat -ano | findstr {global_netstat_filter}\");\n", + "\tvar message = HttpClientStudy.Core.Utilities.AppUtility.RunCmd($\"netstat -ano | findstr {global_netstat_filter}\");\n", "\tConsole.WriteLine(message);\n", "}" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "dotnet_interactive": { "language": "pwsh" @@ -566,7 +587,16 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " TCP 192.168.1.151:18018 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18019 47.103.77.66:80 ESTABLISHED 32156\n" + ] + } + ], "source": [ "# 重新查询当前网络状态\n", "#!set --value @csharp:global_netstat_filter --name queryFilter\n", @@ -582,7 +612,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -594,7 +624,30 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "开始请求网络...\n", + "共请求了200次,耗时 11781 毫秒\n", + "当前网络状态\n", + " TCP 192.168.1.151:18018 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18019 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18167 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18168 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18169 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18170 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18171 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18172 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18173 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18174 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18175 47.103.77.66:80 ESTABLISHED 32156\n", + " TCP 192.168.1.151:18176 47.103.77.66:80 ESTABLISHED 32156\n", + "\n" + ] + } + ], "source": [ "{ //MaxConnectionsPerServer 设置为10:网络连接将增加到10个,耗时将减少到1/4\n", "\tConsole.WriteLine(\"开始请求网络...\");\n", @@ -619,7 +672,7 @@ "\t\t\n", "\t//执行查看网络状态方法\n", "\tConsole.WriteLine(\"当前网络状态\");\n", - "\tvar message = CmdUtility.RunCmd($\"netstat -ano | findstr {global_netstat_filter}\");\n", + "\tvar message = AppUtility.RunCmd($\"netstat -ano | findstr {global_netstat_filter}\");\n", "\tConsole.WriteLine(message);\n", "}" ] @@ -661,7 +714,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -712,7 +765,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 7, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -728,7 +781,7 @@ { "data": { "text/html": [ - "
Installed Packages
  • Microsoft.Extensions.Http.Resilience, 8.5.0
  • Polly, 8.4.0
" + "
Installed Packages
  • Microsoft.Extensions.Http.Resilience, 8.6.0
  • Polly, 8.4.1
" ] }, "metadata": {}, @@ -738,7 +791,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "共有9193个字符\r\n" + "共有227个字符\r\n" ] } ], diff --git a/Docs/1.3.0.基础使用.管理客户端.ipynb b/Docs/1.3.0.基础使用.管理客户端.ipynb index b22a6c6..27397ec 100644 --- a/Docs/1.3.0.基础使用.管理客户端.ipynb +++ b/Docs/1.3.0.基础使用.管理客户端.ipynb @@ -25,7 +25,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 5, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -57,7 +57,7 @@ { "data": { "text/plain": [ - "C:\\Users\\ruyu\\.nuget\\packages\\microsoft.dotnet-interactive\\1.0.522904\\tools\\net8.0\\any\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.dll" + "c:\\Users\\ruyu\\Desktop\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.exe" ] }, "metadata": {}, @@ -67,7 +67,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "命令已在新窗口执行!\r\n" + "程序[c:\\Users\\ruyu\\Desktop\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.exe]已在新的命令行窗口执行。如果未出现新命令行窗口,可能是程序错误造成窗口闪现!\r\n" ] } ], @@ -86,9 +86,9 @@ "//启动已发布的WebApi项目\n", "Console.WriteLine(\"启动WebApi项目\");\n", "var workDir = Environment.CurrentDirectory;\n", - "var fullPath = System.IO.Path.GetFullPath(\"./Publish/HttpClientStudy.WebApp/HttpClientStudy.WebApp.dll\",workDir);\n", + "var fullPath = System.IO.Path.GetFullPath(\"./Publish/HttpClientStudy.WebApp/HttpClientStudy.WebApp.exe\", workDir);\n", "fullPath.Display();\n", - "var startMessage = DotnetCommondUtility.ExecuteCommand(\"exec\",fullPath,true);\n", + "var startMessage = AppUtility.RunWebApiExeFile(fullPath);\n", "Console.WriteLine(startMessage);\n" ] }, @@ -127,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -139,7 +139,17 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "第 10 次/ 共 10 次请求,成功!" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "/*\n", " 每次请求都实例化:并发量大、请求频繁进会耗尽套接字端口\n", diff --git a/HttpClientStudy.Core/Utilities/AppUtility.cs b/HttpClientStudy.Core/Utilities/AppUtility.cs index 1ba33fc..a28d686 100644 --- a/HttpClientStudy.Core/Utilities/AppUtility.cs +++ b/HttpClientStudy.Core/Utilities/AppUtility.cs @@ -18,9 +18,9 @@ namespace HttpClientStudy.Core.Utilities /// 获取应用运行时各种路径 /// /// - public static IDictionary GetApplicationPaths() + public static IDictionary GetApplicationPaths() { - var pathDic = new Dictionary() + var pathDic = new Dictionary() { //当前运行的exe的完整路径,包含exe文件名,只用于WinForm {"Application.ExecutablePath",("程序集基完整路径(仅WinForm)", "Application.ExecutablePath 只适用于WinForm") }, @@ -64,5 +64,233 @@ namespace HttpClientStudy.Core.Utilities return pathDic; } + + /// + /// 启动webapi项目 + /// (出现webapi项目启动命令行窗口) + /// + public static void StartWebApiProject() + { + string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName; + + //webapi项目不在运行状态则启动webapi项目 + if (WebAppIsRunningByMutex(projectAndMutexName) == false) + { + //VS项目根目录 + string vsProjectPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)!.Parent!.Parent!.Parent!.Parent!.FullName; + + //webapi项目根项目 + string webApiProjectPath = Path.Combine(vsProjectPath, projectAndMutexName); + + //启动命令信息 + var prossInfo = new System.Diagnostics.ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}") + { + UseShellExecute = true, + CreateNoWindow = false, + RedirectStandardOutput = false + }; + + //启动 + Process.Start(prossInfo); + } + } + + /// + /// 关闭webapi项目 + /// + public static void ExitWebApiProject() + { + string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName; + + //webapi为运行状态则关闭 + if (WebAppIsRunningByMutex(projectAndMutexName)) + { + var webApiProcess = System.Diagnostics.Process.GetProcessesByName(projectAndMutexName); + + if (webApiProcess != null && webApiProcess.Length > 0) + { + webApiProcess[0].Kill(); + } + } + + } + + /// + /// 运行WebApi发布程序 + /// + /// + public static string RunWebApiExeFile(string exeFile, bool stayWindows = false, params string[] args) + { + string executedMessage = string.Empty; + try + { + if (!Path.IsPathRooted(exeFile)) + { + exeFile = Path.GetFullPath(exeFile, Environment.CurrentDirectory); + } + + if (!File.Exists(exeFile)) + { + executedMessage = $"可执行文件[{exeFile}]不存在"; + return executedMessage; + } + + string fileName = Path.GetFileNameWithoutExtension(exeFile); + + string stayWindowsArg = stayWindows ? "/k" : "/c"; + + string systemShell = "cmd.exe"; + + //string webApiArgs = $"{stayWindowsArg} start \"{fileName}\" \"{exeFile}\" {string.Join(" ", args)}"; + //或者 + string webApiArgs = $"{stayWindowsArg} start \"{fileName}\" \"\"\"{exeFile}\" {string.Join(" ", args)}"; + + ProcessStartInfo startInfo = new ProcessStartInfo() + { + FileName = systemShell, + Arguments = webApiArgs, + + //未知原因:只有 UseShellExecute 设置为 true 时,CreateNoWindow参数才有效,新窗口执行才实际有效。 + UseShellExecute = true, + + //true时不创建新窗口,false才是创建新窗口 + CreateNoWindow = false, + }; + + + //启动进程 + using (Process process = new Process() { StartInfo = startInfo }) + { + process.Start(); + } + + executedMessage = $"程序[{exeFile}]已在新的命令行窗口执行。如果未出现新命令行窗口,可能是程序错误造成窗口闪现!"; + } + catch (Exception ex) + { + executedMessage = $"启动程序[{exeFile}]出现异常:[{ex.Message}]"; + } + finally + { + + } + + return executedMessage; + } + + /// + /// 强制停止WebApi程序 + /// + /// + public static string StopWebApiExeFile() + { + string executedMessage = string.Empty; + + string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName; + try + { + if (WebAppIsRunningByProcessName(projectAndMutexName)) + { + var webApiProcess = Process.GetProcessesByName(projectAndMutexName)?.FirstOrDefault(); + webApiProcess?.Kill(); + + executedMessage = $"WebApi程序[进程号:{webApiProcess?.Id},进程名:{webApiProcess?.ProcessName}],已关闭!"; + } + else + { + executedMessage = $"WebApi程序,未在运行!"; + } + } + catch (Exception ex) + { + executedMessage = $"强制停止WebApi程序时,异常:{ex.Message}"; + } + + return executedMessage; + } + + /// + /// 互斥锁是否存在 + /// + /// 互斥锁名称 + /// 是否存在 + public static bool WebAppIsRunningByMutex(string mutexName) + { + bool createdResult = true; + + //创建互斥锁 + using (var mutex = new Mutex(true, mutexName, out createdResult)) + { + if (createdResult) + { + mutex.ReleaseMutex(); + } + } + + //互斥锁是否创建成功 + return !createdResult; + } + + /// + /// 进程是否存在 + /// + /// 进程名 + /// 是否存在 + public static bool WebAppIsRunningByProcessName(string processName) + { + bool processExists = Process.GetProcessesByName(processName).ToList().Count == 0; + + return processExists; + } + + /// + /// 执行CMD命令 + /// + /// CMD命令 + /// 命令参数 + /// + public static string RunCmd(string command, params string[] args) + { + string executedMessage = string.Empty; + try + { + ProcessStartInfo startInfo = new ProcessStartInfo() + { + FileName = "cmd", + + Arguments = $"/c {command} {string.Join(" ",args)}", + + // 重定向标准输出 + RedirectStandardOutput = true, + + // 不使用系统外壳程序启动 + UseShellExecute = false, + + // 不创建新窗口 + CreateNoWindow = true + }; + + // 启动进程 + using (Process? process = Process.Start(startInfo)) + { + // 读取cmd的输出 + using (StreamReader? reader = process?.StandardOutput) + { + executedMessage = reader?.ReadToEnd() ?? ""; + } + } + } + catch (Exception ex) + { + executedMessage = $"执行命令[{command}]出现异常:[{ex.Message}]"; + } + finally + { + + } + + return executedMessage; + } + } } diff --git a/HttpClientStudy.Core/Utilities/DotnetCommondUtility.cs b/HttpClientStudy.Core/Utilities/DotnetCommondUtility.cs deleted file mode 100644 index c43f6eb..0000000 --- a/HttpClientStudy.Core/Utilities/DotnetCommondUtility.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace HttpClientStudy.Core.Utilities -{ - /// - /// dotnet命令行工具类 - /// - public static class DotnetCommondUtility - { - /// - /// 执行dotnet命令 - /// - /// 命令 - /// 命令参数 - /// 新窗口执行命令 - /// 命令行输出文本 - public static string ExecuteCommand(string command, string argument = "", bool newWindow = false) - { - string output = ""; - - try - { - if (newWindow) - { - ProcessStartInfo startInfo = new ProcessStartInfo() - { - FileName = "pwsh.exe", - Arguments = $" Start-Process -FilePath 'dotnet' {command} {argument}", - //RedirectStandardOutput = true, - //StandardOutputEncoding = Encoding.UTF8, - //RedirectStandardError = true, - //StandardErrorEncoding = Encoding.UTF8, - //RedirectStandardInput = false, - //StandardInputEncoding = Encoding.UTF8, - UseShellExecute = false, - CreateNoWindow = false, - }; - - - Process process = new Process() - { - StartInfo = startInfo, - }; - - process.Start(); - - output = "命令已在新窗口执行!"; - } - else - { - ProcessStartInfo startInfo = new ProcessStartInfo() - { - FileName = "dotnet", - Arguments = $"{command} {argument}", - RedirectStandardOutput = true, - StandardOutputEncoding = Encoding.UTF8, - RedirectStandardError = true, - StandardErrorEncoding = Encoding.UTF8, - //RedirectStandardInput = false, - //StandardInputEncoding = Encoding.UTF8, - - //启用内核模式时,不能重定向输出 - UseShellExecute = false, - - //不创建新窗口 - CreateNoWindow = false, - }; - - Process process = new Process() - { - StartInfo = startInfo, - }; - - //处理输出 - process.OutputDataReceived += (sender, args) => - { - if (!string.IsNullOrEmpty(args.Data)) - { - output += args.Data; - } - }; - - process.Start(); - - //开始异步读取输出 - process.BeginOutputReadLine(); - - //等待里程结束 - process.WaitForExit(); - } - } - catch (Exception ex) - { - output = $"An error occurred: {ex.Message}"; - } - - return output; - } - - /// - /// 新窗口启动WebApp项目 - /// - /// 包含全路径的WebApp项目 - /// 命令参数 - /// - public static string RunWebApp(string startFile, params string[] args) - { - string output = ""; - - try - { - ProcessStartInfo startInfo = new ProcessStartInfo() - { - FileName = "powershell.exe", - Arguments = $"Start-Process -FilePath '{startFile}' -ArgumentList '{string.Join(" ", args)}' ", - UseShellExecute = true, - CreateNoWindow = false, - }; - - - Process process = new Process() - { - StartInfo = startInfo, - }; - - process.Start(); - - output = "已在新窗口中启动WebApp项目。如果已有实例在运行或者执行异常,则窗口会自动关闭;否则新窗口一直存在,直到手动关闭!"; - - } - catch (Exception ex) - { - output = $"An error occurred: {ex.Message}"; - } - - return output; - } - - /// - /// 停止WebAPI项目 - /// - /// 包含全路径的可执行文件 - /// - public static string SopWebApp() - { - string output = ""; - - try - { - string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName; - - ProcessStartInfo startInfo = new ProcessStartInfo() - { - FileName = "powershell.exe", - Arguments = $"Stop-Process -Name '{projectAndMutexName}'", - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardOutput = true, - StandardOutputEncoding = Encoding.UTF8, - }; - - - Process process = new Process() - { - StartInfo = startInfo, - }; - - process.Start(); - - process.WaitForExit(); - - output = process.StandardOutput.ReadToEnd(); - - } - catch (Exception ex) - { - output = $"An error occurred: {ex.Message}"; - } - - return output; - } - } -} diff --git a/HttpClientStudy.Core/Utilities/StartupUtility.cs b/HttpClientStudy.Core/Utilities/StartupUtility.cs deleted file mode 100644 index c6ccee5..0000000 --- a/HttpClientStudy.Core/Utilities/StartupUtility.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace HttpClientStudy.Core.Utilities -{ - /// - /// 启动工具类 - /// - public static class StartupUtility - { - /// - /// 启动webapi项目 - /// (出现webapi项目启动命令行窗口) - /// - public static void StartWebApiProject() - { - string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName; - - //webapi项目不在运行状态则启动webapi项目 - if (webAppIsRunningByMutex() == false) - { - //VS项目根目录 - string vsProjectPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)!.Parent!.Parent!.Parent!.Parent!.FullName; - - //webapi项目根项目 - string webApiProjectPath = Path.Combine(vsProjectPath, projectAndMutexName); - - //启动命令信息 - var prossInfo = new System.Diagnostics.ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}") - { - UseShellExecute = true, - CreateNoWindow = false, - RedirectStandardOutput = false - }; - - //启动 - System.Diagnostics.Process.Start(prossInfo); - } - - //由进程名判断 - //bool webAppIsRunningByProcessName() - //{ - // return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0; - //} - - //由互斥锁判断 - bool webAppIsRunningByMutex() - { - bool createdResult = true; - - //创建互斥锁 - using (var mutex = new Mutex(true, projectAndMutexName, out createdResult)) - { - if (createdResult) - { - mutex.ReleaseMutex(); - } - } - - //互斥锁是否创建成功 - return !createdResult; - } - - } - - /// - /// 关闭webapi项目 - /// - public static void ExitWebApiProject() - { - string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName; - - //webapi为运行状态则关闭 - if (webAppIsRunningByMutex()) - { - var webApiProcess = System.Diagnostics.Process.GetProcessesByName(projectAndMutexName); - - if (webApiProcess != null && webApiProcess.Length>0) - { - webApiProcess[0].Kill(); - } - } - - //由进程名判断 - //bool webAppIsRunningByProcessName() - //{ - // return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0; - //} - - //由互斥锁判断 - bool webAppIsRunningByMutex() - { - bool createdResult = true; - - //创建互斥锁 - using (var mutex = new Mutex(true, projectAndMutexName, out createdResult)) - { - if (createdResult) - { - mutex.ReleaseMutex(); - } - } - - //互斥锁是否创建成功 - return !createdResult; - } - } - } -} diff --git a/HttpClientStudy.UnitTest/UtilitiesTest/AppUtilityTest.cs b/HttpClientStudy.UnitTest/UtilitiesTest/AppUtilityTest.cs index f09ce85..f70a69e 100644 --- a/HttpClientStudy.UnitTest/UtilitiesTest/AppUtilityTest.cs +++ b/HttpClientStudy.UnitTest/UtilitiesTest/AppUtilityTest.cs @@ -29,5 +29,14 @@ namespace HttpClientStudy.UnitTest.UtilitiesTest _output.WriteLine(message); } + + [Fact] + public void Cmd_Test() + { + string message = string.Empty; + message = AppUtility.RunCmd("netstat -ano"); + + _output.WriteLine(message); + } } } diff --git a/HttpClientStudy.UnitTest/UtilitiesTest/DotnetCommondUtilityTest.cs b/HttpClientStudy.UnitTest/UtilitiesTest/DotnetCommondUtilityTest.cs deleted file mode 100644 index 2993614..0000000 --- a/HttpClientStudy.UnitTest/UtilitiesTest/DotnetCommondUtilityTest.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using HttpClientStudy.Core.Utilities; - -namespace HttpClientStudy.UnitTest.UtilitiesTest -{ - public class DotnetCommondUtilityTest - { - private readonly ITestOutputHelper _output; - public DotnetCommondUtilityTest(ITestOutputHelper testOutput) - { - _output = testOutput; - } - - [Fact] - public void Version_Test() - { - var result = DotnetCommondUtility.ExecuteCommand("","--version"); - - _output.WriteLine(result); - } - - [Fact] - public void Info_Test() - { - var result = DotnetCommondUtility.ExecuteCommand("", "--info"); - - _output.WriteLine(result); - } - - [Fact] - public void Help_Test() - { - var result = DotnetCommondUtility.ExecuteCommand("", "--help",true); - - _output.WriteLine(result); - } - } -} diff --git a/HttpClientStudy.UnitTest/startup.cs b/HttpClientStudy.UnitTest/startup.cs index ca9268e..266f114 100644 --- a/HttpClientStudy.UnitTest/startup.cs +++ b/HttpClientStudy.UnitTest/startup.cs @@ -45,7 +45,7 @@ namespace HttpClientStudy.UnitTest public void ConfigureHost(IHostBuilder hostBuilder) { //确保启动 webapi 项目 - StartupUtility.StartWebApiProject(); + AppUtility.StartWebApiProject(); hostBuilder //主机配置设置 diff --git a/HttpClientStudy.WebClient/Controllers/ManagerController.cs b/HttpClientStudy.WebClient/Controllers/ManagerController.cs index fcd3236..0006b12 100644 --- a/HttpClientStudy.WebClient/Controllers/ManagerController.cs +++ b/HttpClientStudy.WebClient/Controllers/ManagerController.cs @@ -25,7 +25,7 @@ namespace HttpClientStudy.WebClient.Controllers [HttpGet] public IActionResult StartWebApi() { - StartupUtility.StartWebApiProject(); + AppUtility.StartWebApiProject(); return Ok("启动成功"); } @@ -37,7 +37,7 @@ namespace HttpClientStudy.WebClient.Controllers [HttpGet] public IActionResult ExitWebApi() { - StartupUtility.ExitWebApiProject(); + AppUtility.ExitWebApiProject(); return Ok("进程已退出"); } diff --git a/HttpClientStudy.WebClient/Program.cs b/HttpClientStudy.WebClient/Program.cs index 8c16987..32be86b 100644 --- a/HttpClientStudy.WebClient/Program.cs +++ b/HttpClientStudy.WebClient/Program.cs @@ -3,7 +3,7 @@ using HttpClientStudy.Core.Utilities; //启动WebApi程序 -StartupUtility.StartWebApiProject(); +AppUtility.StartWebApiProject(); var builder = WebApplication.CreateBuilder(args); @@ -41,7 +41,7 @@ var applicationLifetime = app.Services.GetRequiredService { //注意:在 Visual Studio 2022 预览版中,执行时异常;正式版中正常。应该是预案版的Bug - StartupUtility.ExitWebApiProject(); + AppUtility.ExitWebApiProject(); }); applicationLifetime.ApplicationStopped.Register(() =>