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.

310 lines
12 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>
/// <param name="exeFile">WebApi程序文件</param>
/// <param name="args">WebApi启动参数</param>
/// <param name="stayWindow">是否保持命令窗口(不关闭)</param>
/// <returns></returns>
public static string RunWebApiExeFile(string exeFile, bool stayWindow = 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 systemShell = "cmd.exe";
string cmdArgsText = string.Empty;
//保持新命令窗口(不自动关闭)
if (stayWindow)
{
cmdArgsText = $"/c start \"{fileName}\" cmd /k \"\"\"{exeFile}\" {string.Join(" ",args)}";
}
else
{
cmdArgsText = $"/c start \"{fileName}\" \"\"\"{exeFile}\" {string.Join(" ",args)}";
}
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = systemShell,
Arguments = cmdArgsText,
//执行命令的线程本身不弹出新窗口
//确保弹出新窗口是使用cmd start 实现
//保持新窗口不关闭:使用 start cmd /k 实现
UseShellExecute = false,
//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>
/// 执行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;
}
/// <summary>
/// 互斥锁是否存在
/// </summary>
/// <param name="mutexName">互斥锁名称</param>
/// <returns>是否存在</returns>
private 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>
private static bool WebAppIsRunningByProcessName(string processName)
{
bool processExists = Process.GetProcessesByName(processName).ToList().Count == 0;
return processExists;
}
}
}