C#System.Management.Automation.PowerShell性能

时间:2014-09-25 23:25:18

标签: c# powershell powershell-v2.0 system.management

为什么直接从PowerShell执行脚本的性能比从System.Management.Automation.PowerShell类执行脚本要快得多?当我直接在PS中执行我的脚本时,它只需不到一秒钟,但是当我通过下面的代码执行它时,Invoke需要几分钟。

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;
    }
}

0 个答案:

没有答案