为什么直接从 PowerShell 执行脚本的性能比从 System.Management.Automation.PowerShell 类执行脚本时快得多?当我直接在 PS 中执行我的脚本时,它需要不到一秒钟,但是当我通过下面的代码执行它时,调用需要几分钟。
public bool Execute(string filename, out string result)
{
StringBuilder sb = new StringBuilder();
using (PowerShell ps = PowerShell.Create())
{
ps.Runspace.SessionStateProxy.SetVariable("filename", filename);
ps.AddScript(this.script);
Collection<PSObject> psOutput = ps.Invoke();
foreach (PSObject item in psOutput)
{
Console.WriteLine(item);
}
PSDataCollection<ErrorRecord> errors = ps.Streams.Error;
foreach (ErrorRecord err in errors)
{
Console.WriteLine(err);
}
result = sb.ToString();
return errors.Count == 0;
}
}
脚本文本:
[regex]$r = "\$\%\$@@(.+)\$\%\$@@";
(Get-Content $filename) |
Foreach-Object {
$line = $_;
$find = $r.matches($line);
if ($find[0].Success) {
foreach ($match in $find) {
$found = $match.value
$replace = $found -replace "[^A-Za-z0-9\s]", "";
$line.Replace($found, $replace);
}
}
else
{
$line;
}
} |
Set-Content $filename
我在c#中针对这个方法测试了脚本的执行,这个方法执行脚本的时间不到2秒。
public bool Execute(string filename, out string result)
{
StringBuilder standardOutput = new StringBuilder();
string currentPath = Path.GetDirectoryName(filename);
string psFile = Path.Combine(currentPath, Path.GetFileNameWithoutExtension(Path.GetRandomFileName()) + ".ps1");
this.script = this.script.Replace("$filename", "\"" + filename + "\"");
File.WriteAllText(psFile, this.script);
using (Process process = new Process())
{
process.StartInfo = new ProcessStartInfo("powershell.exe", String.Format("-executionpolicy unrestricted \"{0}\"", psFile))
{
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardOutput = true
};
process.Start();
var output = process.StandardOutput.ReadToEnd();
while (!process.HasExited)
{
standardOutput.Append(process.StandardOutput.ReadToEnd());
}
process.WaitForExit();
standardOutput.Append(process.StandardOutput.ReadToEnd());
result = standardOutput.ToString();
return process.ExitCode == 0;
}
}