diff --git a/ExecuteCommandStudy.CApp/ExecuteCommandStudy.CApp.csproj b/ExecuteCommandStudy.CApp/ExecuteCommandStudy.CApp.csproj
new file mode 100644
index 0000000..fca895a
--- /dev/null
+++ b/ExecuteCommandStudy.CApp/ExecuteCommandStudy.CApp.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/ExecuteCommandStudy.CApp/Program.cs b/ExecuteCommandStudy.CApp/Program.cs
new file mode 100644
index 0000000..d126668
--- /dev/null
+++ b/ExecuteCommandStudy.CApp/Program.cs
@@ -0,0 +1,10 @@
+namespace ExecuteCommandStudy.CApp
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Hello, World!");
+ }
+ }
+}
diff --git a/ExecuteCommandStudy.Core/AppUtility.cs b/ExecuteCommandStudy.Core/AppUtility.cs
new file mode 100644
index 0000000..c1bf68a
--- /dev/null
+++ b/ExecuteCommandStudy.Core/AppUtility.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+
+
+namespace ExecuteCommandStudy.Core
+{
+ ///
+ /// 应用工具类
+ ///
+ public class AppUtility
+ {
+ ///
+ /// 获取应用运行时各种路径
+ ///
+ ///
+ public static IDictionary GetApplicationPaths()
+ {
+ var pathDic = new Dictionary()
+ {
+ //当前运行的exe的完整路径,包含exe文件名,只用于WinForm
+ {"Application.ExecutablePath",("程序集基完整路径(仅WinForm)", "Application.ExecutablePath 只适用于WinForm") },
+
+ //程序的启动路径:只用于WinForm
+ {"Application.StartupPath",("程序集启动路径(仅WinForm)", "Application.StartupPath 只适用于WinForm") },
+
+ //当前执行的exe或启动项目的路径,通过AppContext
+ {"AppContext.BaseDirectory",("执行或启动路径",AppContext.BaseDirectory) },
+
+ //当前执行的exe的目录,不包含exe名,使用AppDomain
+ {"AppDomain.CurrentDomain.BaseDirectory",("程序集解析程序用于探测程序集的基目录",AppDomain.CurrentDomain.BaseDirectory) },
+
+ //程序安装或启动基目录 包含应用程序的目录的名称
+ {"AppDomain.CurrentDomain.SetupInformation.ApplicationBase",("程序安装或启动基目录",AppDomain.CurrentDomain.SetupInformation.ApplicationBase) },
+
+ //当前进程的主模块路径,包含exe名
+ {"Process.GetCurrentProcess().MainModule.FileName",("当前进程的主模块路径",Process.GetCurrentProcess()?.MainModule?.FileName) },
+
+ //环境变量:用户当前工作目录的完整限定路径
+ {"Environment.CurrentDirectory",("用户当前工作目录的完整限定路径",Environment.CurrentDirectory) },
+
+ //环境变量:当前exe的完整路径,包含exe名,通过命令行参数
+ {"Environment.GetCommandLineArgs()[0]",("当前exe的完整路径",Environment.GetCommandLineArgs()[0]) },
+
+ //当前工作目录的路径(可变)
+ {"Directory.GetCurrentDirectory",("当前工作目录的路径(可变)",Directory.GetCurrentDirectory()) },
+
+ //当前Assembly的加载路径,包含dll或exe名
+ {"Assembly.GetExecutingAssembly().Location",("当前Assembly的加载路径",Assembly.GetExecutingAssembly().Location) },
+
+ //入口程序集的路径
+ {"Assembly.GetEntryAssembly().Location",("入口程序集的路径",Assembly.GetEntryAssembly()?.Location) },
+ };
+
+ return pathDic;
+ }
+ }
+}
diff --git a/ExecuteCommandStudy.Core/DotnetCommondUtility.cs b/ExecuteCommandStudy.Core/DotnetCommondUtility.cs
new file mode 100644
index 0000000..4da692c
--- /dev/null
+++ b/ExecuteCommandStudy.Core/DotnetCommondUtility.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ExecuteCommandStudy.Core
+{
+ ///
+ /// 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' -ArgumentList '{command}','{argument}'",
+ //RedirectStandardOutput = true,
+ //StandardOutputEncoding = Encoding.UTF8,
+ //RedirectStandardError = true,
+ //StandardErrorEncoding = Encoding.UTF8,
+ //RedirectStandardInput = false,
+ //StandardInputEncoding = Encoding.UTF8,
+ UseShellExecute = true,
+ 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 = "xxxxxxx";
+
+ 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/ExecuteCommandStudy.Core/ExecuteCommandStudy.Core.csproj b/ExecuteCommandStudy.Core/ExecuteCommandStudy.Core.csproj
new file mode 100644
index 0000000..fa71b7a
--- /dev/null
+++ b/ExecuteCommandStudy.Core/ExecuteCommandStudy.Core.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/ExecuteCommandStudy.Core/GlobalUsing.cs b/ExecuteCommandStudy.Core/GlobalUsing.cs
new file mode 100644
index 0000000..4863fb3
--- /dev/null
+++ b/ExecuteCommandStudy.Core/GlobalUsing.cs
@@ -0,0 +1,4 @@
+global using System;
+
+global using System.Text;
+global using System.Diagnostics;
\ No newline at end of file
diff --git a/ExecuteCommandStudy.Core/StartupUtility.cs b/ExecuteCommandStudy.Core/StartupUtility.cs
new file mode 100644
index 0000000..2de8295
--- /dev/null
+++ b/ExecuteCommandStudy.Core/StartupUtility.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ExecuteCommandStudy.Core
+{
+ ///
+ /// 启动工具类
+ ///
+ public static class StartupUtility
+ {
+ ///
+ /// 启动webapi项目
+ /// (出现webapi项目启动命令行窗口)
+ ///
+ public static void StartWebApiProject()
+ {
+ string projectAndMutexName = "xxx";
+
+ //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/ExecuteCommandStudy.Core/Utils1.cs b/ExecuteCommandStudy.Core/Utils1.cs
new file mode 100644
index 0000000..1282fc0
--- /dev/null
+++ b/ExecuteCommandStudy.Core/Utils1.cs
@@ -0,0 +1,186 @@
+namespace ExecuteCommandStudy.Core
+{
+ public static class Utils1
+ {
+ static void A()
+ {
+ ProcessStartInfo startInfo = new ProcessStartInfo();
+ startInfo.FileName = "cmd.exe";
+ startInfo.Arguments = "/u /k dotnet exec c:\\Users\\ruyu\\Desktop\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.dll";
+ startInfo.UseShellExecute = false;
+ startInfo.CreateNoWindow = false;
+
+ Process.Start(startInfo);
+ }
+
+ ///
+ /// 启动WebApi程序
+ ///
+ /// 带相对或绝对路径的可执行文件
+ /// 应用程序参数
+ static string B(string exePathAndName, params string[] args)
+ {
+ string executedMessage = string.Empty;
+ try
+ {
+ if (!Path.IsPathRooted(exePathAndName))
+ {
+ exePathAndName = Path.GetFullPath(exePathAndName, Environment.CurrentDirectory);
+ }
+
+ if (!File.Exists(exePathAndName))
+ {
+ executedMessage = $"可执行文件[{exePathAndName}]不存在";
+ return executedMessage;
+ }
+
+ ProcessStartInfo startInfo = new ProcessStartInfo();
+ startInfo.FileName = exePathAndName;
+ startInfo.Arguments = string.Join(" ", args);
+
+ //未知原因:只有 UseShellExecute 设置为 true 时,CreateNoWindow参数才有效,新窗口执行才实际有效。
+ startInfo.UseShellExecute = true;
+
+ //true时不创建新窗口,false才是创建新窗口
+ startInfo.CreateNoWindow = false;
+
+ //启动进程
+ using (Process process = new Process() { StartInfo = startInfo })
+ {
+ process.Start();
+ }
+
+ executedMessage = $"程序[{exePathAndName}]已在新的命令行窗口执行。如果未出现新命令行窗口,可能是程序错误造成窗口闪现!";
+ }
+ catch (Exception ex)
+ {
+ executedMessage = $"启动程序[{exePathAndName}]出现异常:[{ex.Message}]";
+ }
+ finally
+ {
+
+ }
+
+ return executedMessage;
+ }
+
+ static void PowerShell()
+ {
+ // 创建新的进程开始信息
+ ProcessStartInfo startInfo = new ProcessStartInfo()
+ {
+ FileName = "powershell.exe",
+ Arguments = $"Start-Process powershell -ArgumentList '-noexit','-command','dotnet c:\\Users\\ruyu\\Desktop\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.dll'",
+
+ UseShellExecute = false,
+ RedirectStandardOutput = false,
+ CreateNoWindow = false // 设置为false以在新窗口中打开
+ };
+
+ try
+ {
+ // 使用启动信息创建并启动进程
+ using (Process process = new Process() { StartInfo = startInfo })
+ {
+ process.Start();
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("An error occurred: " + e.Message);
+ }
+ }
+
+ static void RunExe()
+ {
+ // PowerShell();
+
+ var webapiExe = "c:\\Users\\ruyu\\Desktop\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.exe";
+
+ // 创建新的进程开始信息
+ ProcessStartInfo startInfo = new ProcessStartInfo()
+ {
+ FileName = "powershell.exe",
+ Arguments = $"Start-Process {webapiExe} -ArgumentList '-noexit'",
+
+ UseShellExecute = false,
+ RedirectStandardOutput = false,
+ CreateNoWindow = false // 设置为false以在新窗口中打开
+ };
+
+ try
+ {
+ // 使用启动信息创建并启动进程
+ using (Process process = new Process() { StartInfo = startInfo })
+ {
+ process.Start();
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("An error occurred: " + e.Message);
+ }
+ }
+
+ ///
+ /// 运行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)}";
+
+ 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;
+ }
+ }
+}
diff --git a/ExecuteCommandStudy.Test/ExecuteCommandStudy.Test.csproj b/ExecuteCommandStudy.Test/ExecuteCommandStudy.Test.csproj
new file mode 100644
index 0000000..3181b74
--- /dev/null
+++ b/ExecuteCommandStudy.Test/ExecuteCommandStudy.Test.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ExecuteCommandStudy.Test/UnitTest1.cs b/ExecuteCommandStudy.Test/UnitTest1.cs
new file mode 100644
index 0000000..5abdffa
--- /dev/null
+++ b/ExecuteCommandStudy.Test/UnitTest1.cs
@@ -0,0 +1,11 @@
+namespace ExecuteCommandStudy.Test
+{
+ public class UnitTest1
+ {
+ [Fact]
+ public void Test1()
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/ExecuteCommandStudy.sln b/ExecuteCommandStudy.sln
new file mode 100644
index 0000000..d5e671e
--- /dev/null
+++ b/ExecuteCommandStudy.sln
@@ -0,0 +1,36 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.35013.160
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExecuteCommandStudy.CApp", "ExecuteCommandStudy.CApp\ExecuteCommandStudy.CApp.csproj", "{05C727B6-7A38-476D-8D6C-62A26B7BEF3D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExecuteCommandStudy.Test", "ExecuteCommandStudy.Test\ExecuteCommandStudy.Test.csproj", "{DD1D2861-2D56-4279-81DA-447ADF1A3343}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExecuteCommandStudy.Core", "ExecuteCommandStudy.Core\ExecuteCommandStudy.Core.csproj", "{F2AF0EC2-D892-4079-8306-D974A1757F34}"
+EndProject
+Global
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {EC5B6915-A92D-4B38-B717-94AEBE296A64}
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {05C727B6-7A38-476D-8D6C-62A26B7BEF3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {05C727B6-7A38-476D-8D6C-62A26B7BEF3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {05C727B6-7A38-476D-8D6C-62A26B7BEF3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {05C727B6-7A38-476D-8D6C-62A26B7BEF3D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DD1D2861-2D56-4279-81DA-447ADF1A3343}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DD1D2861-2D56-4279-81DA-447ADF1A3343}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DD1D2861-2D56-4279-81DA-447ADF1A3343}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DD1D2861-2D56-4279-81DA-447ADF1A3343}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F2AF0EC2-D892-4079-8306-D974A1757F34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F2AF0EC2-D892-4079-8306-D974A1757F34}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F2AF0EC2-D892-4079-8306-D974A1757F34}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F2AF0EC2-D892-4079-8306-D974A1757F34}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal