UNIVPLMDataIntegration/Admin.NET/Admin.NET.Core/Utils/CommandLine/ScriptExecutor.cs

146 lines
5.3 KiB
C#

// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 脚本执行助手类,支持执行 .sh、.ps1、.bat 脚本
/// </summary>
public static class ScriptExecutor
{
/// <summary>
/// 执行脚本
/// </summary>
/// <param name="scriptFilePath">脚本文件的完整路径</param>
/// <param name="arguments">传递给脚本的参数</param>
/// <returns>执行结果(标准输出和标准错误)</returns>
public static string ExecuteScript(string scriptFilePath, string arguments = "")
{
if (string.IsNullOrWhiteSpace(scriptFilePath) || !File.Exists(scriptFilePath))
{
throw new ArgumentException("脚本文件不存在", nameof(scriptFilePath));
}
var fileExtension = Path.GetExtension(scriptFilePath).ToLower();
return fileExtension switch
{
".sh" => ExecuteShellScript(scriptFilePath, arguments),
".ps1" => ExecutePowerShellScript(scriptFilePath, arguments),
".bat" => ExecuteBatchScript(scriptFilePath, arguments),
_ => throw new NotSupportedException("不支持的脚本类型")
};
}
/// <summary>
/// 执行 Shell 脚本(Linux/macOS)
/// </summary>
/// <param name="scriptFilePath">脚本文件的完整路径</param>
/// <param name="arguments">传递给脚本的参数</param>
/// <returns>执行结果</returns>
private static string ExecuteShellScript(string scriptFilePath, string arguments)
{
var processStartInfo = new ProcessStartInfo
{
FileName = "/bin/bash", // Linux/macOS 使用 bash 执行脚本
Arguments = $"{scriptFilePath} {arguments}",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
return ExecuteProcess(processStartInfo);
}
/// <summary>
/// 执行 PowerShell 脚本(Windows)
/// </summary>
/// <param name="scriptFilePath">脚本文件的完整路径</param>
/// <param name="arguments">传递给脚本的参数</param>
/// <returns>执行结果</returns>
private static string ExecutePowerShellScript(string scriptFilePath, string arguments)
{
var processStartInfo = new ProcessStartInfo
{
FileName = "powershell", // Windows 使用 PowerShell 执行脚本
Arguments = $"-ExecutionPolicy Bypass -File \"{scriptFilePath}\" {arguments}",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
return ExecuteProcess(processStartInfo);
}
/// <summary>
/// 执行批处理脚本(Windows)
/// </summary>
/// <param name="scriptFilePath">脚本文件的完整路径</param>
/// <param name="arguments">传递给脚本的参数</param>
/// <returns>执行结果</returns>
private static string ExecuteBatchScript(string scriptFilePath, string arguments)
{
var processStartInfo = new ProcessStartInfo
{
FileName = scriptFilePath, // Windows 使用 cmd 执行批处理脚本
Arguments = arguments,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
return ExecuteProcess(processStartInfo);
}
/// <summary>
/// 执行进程并获取输出结果
/// </summary>
/// <param name="processStartInfo">进程启动信息</param>
/// <returns>执行结果</returns>
private static string ExecuteProcess(ProcessStartInfo processStartInfo)
{
var output = new StringBuilder();
var error = new StringBuilder();
try
{
using var process = Process.Start(processStartInfo) ?? throw new InvalidOperationException("无法启动进程");
process.OutputDataReceived += (o, e) =>
{
if (e.Data is not null)
{
o = output.AppendLine(e.Data);
}
};
process.ErrorDataReceived += (o, e) =>
{
if (e.Data is not null)
{
o = error.AppendLine(e.Data);
}
};
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
if (process.ExitCode != 0)
{
throw new Exception($"脚本执行失败,错误信息:{error}");
}
}
catch (Exception ex)
{
return $"执行过程中发生错误:{ex.Message}";
}
return output.ToString();
}
}