正在从Powershell脚本获取输出

本文关键字:获取 输出 脚本 Powershell | 更新日期: 2023-09-27 18:00:08

我正在创建一个MVC4 web应用程序,该应用程序将能够创建一个控制台,使用SignalR将Powershell脚本的输出记录到日志窗口。目前,我所做的最好的工作是在Pipeline.Invoke-shows之后在C#中捕获Powershell输出。问题是,我无法使用此方法将实时输出流传递给客户端。只有在脚本处理完毕后,我才能提供输出。目前我正在尝试这个,但没有收到任何输出。

var loggingHub = new LoggingHub();
string powerShellExeLocation = null;
var localKey = Registry.LocalMachine;
var subKey = localKey.OpenSubKey(@"SOFTWARE'Microsoft'PowerShell'1'PowerShellEngine");
powerShellExeLocation = subKey.GetValue("ApplicationBase").ToString();
if (!Directory.Exists(powerShellExeLocation))
    throw new Exception("Cannot locate the PowerShell dir.");
powerShellExeLocation = Path.Combine(powerShellExeLocation, "powershell.exe");
if (!File.Exists(powerShellExeLocation))
    throw new Exception("Cannot locate the PowerShell executable.");
if (!File.Exists(scriptFile))
    throw new Exception("Cannot locate the PowerShell script.");
var processInfo = new ProcessStartInfo
{
    Verb = "runas",
    UseShellExecute = false,
    RedirectStandardOutput = true
};
processInfo.RedirectStandardOutput = true;
processInfo.WorkingDirectory = Environment.CurrentDirectory;
processInfo.FileName = powerShellExeLocation;
//processInfo.Arguments = "-NoLogo -OutputFormat Text -NonInteractive -WindowStyle Hidden -ExecutionPolicy Unrestricted -File '"" + scriptFile + "'" ";
processInfo.Arguments = build;
var powerShellProcess = new Process {StartInfo = processInfo};
powerShellProcess.Start();
while (!powerShellProcess.HasExited)
{
    loggingHub.Send(DateTime.Now.ToString("h:mm:ss tt"), "info", powerShellProcess.StandardOutput.ReadLine());
}

正在从Powershell脚本获取输出

在输出发生时记录输出的一种方法是不仅托管PowerShell引擎,还实现主机接口。然后,当PowerShell引擎处理脚本时,每次对"主机"进行"写入"时,都会调用您。实现主机接口并不简单,但也不太难。查看此MSDN链接http://msdn.microsoft.com/en-us/windows/desktop/ee706584(v=vs.85)

来源:

http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.110).aspx

**当进程将文本写入其标准流时,该文本通常显示在控制台上。通过重定向StandardOutput流,可以操纵或抑制进程的输出。例如,您可以过滤文本,以不同的方式格式化文本,或者将输出写入控制台和指定的日志文件。笔记如果要将RedirectStandardOutput设置为true,则必须将UseShellExecute设置为false。否则,从StandardOutput流中读取会引发异常。

重定向的StandardOutput流可以同步读取,也可以异步读取。Read、ReadLine和ReadToEnd等方法对进程的输出流执行同步读取操作。这些同步读取操作直到关联的进程写入其StandardOutput流或关闭流后才能完成。相反,BeginOutputReadLine在StandardOutput流上启动异步读取操作。此方法为流输出启用指定的事件处理程序,并立即返回给调用方,调用方可以在流输出指向事件处理程序时执行其他工作。笔记处理异步输出的应用程序应该调用WaitForExit方法,以确保输出缓冲区已被刷新。

同步读取操作在从StandardOutput流读取的调用程序和写入该流的子进程之间引入了依赖关系。这些依赖关系可能会导致死锁情况。当调用方从子进程的重定向流中读取时,它依赖于子进程。调用方等待读取操作,直到子级写入流或关闭流。当子进程写入足够的数据以填充其重定向流时,它依赖于父进程。子进程等待下一次写入操作,直到父进程从完整流中读取或关闭流。当调用方和子进程等待对方完成操作,并且两者都不能继续时,就会出现死锁情况。您可以通过评估调用者和子进程之间的依赖关系来避免死锁。**

这似乎可以解释发生了什么。您是否尝试过使用BeginOutputReadLine方法而不是ReadLine?