65 lines
2.5 KiB
C#
65 lines
2.5 KiB
C#
using System.Diagnostics;
|
||
using System.IO;
|
||
|
||
namespace OneClickRun.Services;
|
||
|
||
/// <summary>定位 PowerShell 7(pwsh.exe)并构造脚本启动参数</summary>
|
||
public static class PowerShellLocator
|
||
{
|
||
/// <summary>依次从 PATH、标准安装目录查找 pwsh.exe</summary>
|
||
public static string? Find()
|
||
{
|
||
var pathVar = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
||
foreach (var dir in pathVar.Split(';', StringSplitOptions.RemoveEmptyEntries))
|
||
{
|
||
var candidate = Path.Combine(dir.Trim(), "pwsh.exe");
|
||
if (File.Exists(candidate)) return candidate;
|
||
}
|
||
var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
|
||
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||
string[] candidates =
|
||
{
|
||
Path.Combine(programFiles, "PowerShell", "7", "pwsh.exe"),
|
||
Path.Combine(localAppData, "Programs", "PowerShell", "7", "pwsh.exe"),
|
||
};
|
||
foreach (var c in candidates)
|
||
if (File.Exists(c)) return c;
|
||
return null;
|
||
}
|
||
|
||
public static string? GetVersion(string? pwshPath)
|
||
{
|
||
if (string.IsNullOrEmpty(pwshPath) || !File.Exists(pwshPath)) return null;
|
||
try
|
||
{
|
||
using var process = Process.Start(new ProcessStartInfo
|
||
{
|
||
FileName = pwshPath,
|
||
Arguments = "-NoProfile -Command \"$PSVersionTable.PSVersion.ToString()\"",
|
||
UseShellExecute = false,
|
||
RedirectStandardOutput = true,
|
||
RedirectStandardError = true,
|
||
CreateNoWindow = true,
|
||
});
|
||
if (process == null) return null;
|
||
var output = process.StandardOutput.ReadToEnd();
|
||
process.WaitForExit(5000);
|
||
return string.IsNullOrWhiteSpace(output) ? null : output.Trim();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Warn($"获取 PowerShell 版本失败: {ex.Message}");
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// <summary>构造 pwsh 启动参数(脚本路径加引号,兼容含空格路径)</summary>
|
||
public static string BuildScriptArguments(string scriptPath, string? extraArgs)
|
||
{
|
||
var quoted = "\"" + scriptPath + "\"";
|
||
return string.IsNullOrWhiteSpace(extraArgs)
|
||
? $"-NoProfile -ExecutionPolicy Bypass -File {quoted}"
|
||
: $"-NoProfile -ExecutionPolicy Bypass -File {quoted} {extraArgs.Trim()}";
|
||
}
|
||
}
|