从powershell脚本捕获输出

时间:2017-12-28 17:37:28

标签: c# wpf powershell

我一直致力于在VS2017中为客户将GUI脚本从另一种语言转换为C#。在这里的人们的帮助下,我95%的方式在那里,但遇到了几个障碍;我不确定我是以最好的方式做事。我只包括以下代码的相关部分,如果我提供的不足,请告诉我们:

大部分代码都集中在wpf表单上,该表单为低级技术人员收集数据,以便将大量虚拟机批量部署到VMware环境中。这个数字可以很容易地同时进入几十甚至一百个虚拟机。每个VM的信息在表单中指定,然后在列表视图中收集。列表视图完全填充后,将导出到csv。到目前为止,一切正常。

我接下来一直在努力实际启动powershell / powerCLI脚本(也正常工作)并捕获输出。使用客户使用的特定读取器应用程序打开日志文件,该应用程序实时更新,并将捕获的输出提供给日志。技术人员必须逐行查看代码的输出,以便在出现问题时做出反应。

我从这样的事情开始作为测试:

string sPSScript = "C:\\Users\\Admin\\Desktop\\TestC#.ps1";
string logFile = "C:\\Users\\Admin\\Desktop\\My.log";
string logReader = "C:\\Users\\Admin\\Documents\\CMTrace.exe";
string standard_output;

System.Diagnostics.Process PSScript = new System.Diagnostics.Process();
PSScript.StartInfo.FileName = 
Environment.GetFolderPath(Environment.SpecialFolder.SystemX86) + 
"\\WindowsPowerShell\\v1.0\\powershell.exe";
PSScript.StartInfo.Arguments = "-command . '" + sPSScript + "' " + 
vCenter.Text;
PSScript.StartInfo.RedirectStandardOutput = true;
PSScript.StartInfo.UseShellExecute = false;
PSScript.Start();
System.Diagnostics.Process LogFile = new System.Diagnostics.Process();
LogFile.StartInfo.FileName = logReader;
LogFile.StartInfo.Arguments = logFile;
LogFile.Start();        while ((standard_output = 
PSScript.StandardOutput.ReadLine()) != null)
    {
       if (standard_output != "")
       {
          using (StreamWriter file = new StreamWriter(logFile, append: true))
             {
                file.WriteLine(standard_output);
             }
       }
   }

虽然这会按预期实时写入日志文件,但它会创建100个logReader应用程序实例。我理解为什么,因为我通过每次传递声明一个新的StreamWriter对象,但我不确定如何更好地解决这个问题。

我尝试在循环外创建文件,如下所示:

StreamWriter file = new StreamWriter(logFile, append: true) { };
System.Diagnostics.Process LogFile = new System.Diagnostics.Process();
LogFile.StartInfo.FileName = logReader;
LogFile.StartInfo.Arguments = logFile;

System.Diagnostics.Process PSScript = new System.Diagnostics.Process();
  PSScript.StartInfo.FileName = Environment.GetFolderPath(Environment.SpecialFolder.SystemX86) + "\\WindowsPowerShell\\v1.0\\powershell.exe";
  PSScript.StartInfo.Arguments = "-command . '" + sPSScript + "' " + vCenter.Text;
  PSScript.StartInfo.RedirectStandardOutput = true;
  PSScript.StartInfo.UseShellExecute = false;

  LogFile.Start();
  PSScript.Start();
  System.Threading.Thread.Sleep(1500);

  while ((standard_output = PSScript.StandardOutput.ReadLine()) != null)
  {
     if (standard_output != "")
     {
        file.WriteLine(standard_output);
     }
  }

它不会创建多个实例,但它也不会像以前的代码那样实时更新日志文件。它仅在脚本运行时更新,然后仅部分更新。该脚本产生约1000行输出,我一直看到只有大约840写入日志文件。

我想过做这样的事情:

FileStream logFS;
logFS = new FileStream(logFile, FileMode.Append);

但似乎我可以写入该文件的唯一选项是期望一个字节数组。

我确信我在这方面遗漏了一些愚蠢的东西,但是会欣赏有关创建日志文件的最简单方法的任何建议,在阅读器中打开它,然后使用powershell脚本的标准输出更新它。

1 个答案:

答案 0 :(得分:1)

为什么之前的代码实时写入?

因为你用using包装它。在using阻止结束时,它会调用dispose,调用.Flush来写入磁盘

您的第二个代码块调用WriteLine但从未调用Flush,因此只要缓冲区已满,它就会写入磁盘。只需在.Flush之后添加WriteLine来电,即可实时记录

相关问题