You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

297 lines
11 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
namespace HttpClientStudy.Core.Utilities
{
/// <summary>
/// 应用工具类
/// </summary>
public class AppUtility
{
/// <summary>
/// 获取应用运行时各种路径
/// </summary>
/// <returns></returns>
public static IDictionary<string, (string desc, string? path)> GetApplicationPaths()
{
var pathDic = new Dictionary<string, (string desc, string? path)>()
{
//当前运行的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) },
//已过时当前程序集的CodeBase路径可能为file URI格式
//{"Assembly.GetExecutingAssembly().CodeBase",("当前程序集的CodeBase路径",Assembly.GetExecutingAssembly()?.CodeBase) },
//已过时入口程序集的CodeBase路径可能为file URI格式
//{"Assembly.GetEntryAssembly().CodeBase",("入口程序集的CodeBase路径",Assembly.GetEntryAssembly()?.CodeBase) },
};
return pathDic;
}
/// <summary>
/// 启动webapi项目
/// (出现webapi项目启动命令行窗口)
/// </summary>
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);
}
}
/// <summary>
/// 关闭webapi项目
/// </summary>
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();
}
}
}
/// <summary>
/// 运行WebApi发布程序
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// 强制停止WebApi程序
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// 互斥锁是否存在
/// </summary>
/// <param name="mutexName">互斥锁名称</param>
/// <returns>是否存在</returns>
public static bool WebAppIsRunningByMutex(string mutexName)
{
bool createdResult = true;
//创建互斥锁
using (var mutex = new Mutex(true, mutexName, out createdResult))
{
if (createdResult)
{
mutex.ReleaseMutex();
}
}
//互斥锁是否创建成功
return !createdResult;
}
/// <summary>
/// 进程是否存在
/// </summary>
/// <param name="processName">进程名</param>
/// <returns>是否存在</returns>
public static bool WebAppIsRunningByProcessName(string processName)
{
bool processExists = Process.GetProcessesByName(processName).ToList().Count == 0;
return processExists;
}
/// <summary>
/// 执行CMD命令
/// </summary>
/// <param name="command">CMD命令</param>
/// <param name="args">命令参数</param>
/// <returns></returns>
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;
}
}
}