通过System.Diagnostics.Process或System.Management.Automation.Runspaces

时间:2015-11-06 11:46:19

标签: powershell process

需要您帮助解决以下问题。

我们有一个PowerShell脚本,如:

invoke-command -ScriptBlock { [cmdletbinding()]
param(
    [parameter(mandatory=$True)]
    [string] $ticktfilepath      
)
$ticketdetails=get-content $ticktfilepath |%{if ( $_ -like '"AB*' ) {$_}}|%{echo "$($_.Split(',')[7].Split('"')[1])=$($_.Split(',')[3].Split(':')[0].Split(' ')[$_.Split(',')[3].Split(':')[0].Split(' ').length-1])=$($_.Split(',')[0].Split('"')[1]);"}
write-output $ticketdetails } -ArgumentList 'D:\file.csv' 

此脚本读取csv文件,并在csv中使用“AB ...”开头的那些行进行一些字符串解析。传递的csv文件包含带有“AB ...”的行,因此返回结果。通过PowerShell控制台或ISE执行时,这可以很好地运行。

但是根据我们的要求,我们尝试通过以下方式执行相同的脚本: 1.具有进程启动信息的System.Diagnostics.Process,其文件名为powershell.exe,以及上述脚本中的参数。它失败了。即|%{if($ _ -like'" AB *')。即使预期是真实的,对于该条件总是错误的。 注:其他的PowerShell脚本与这种方法完美配合 2.通过System.Management.Automation.Runspaces执行时完全相似的问题 所以看起来像使用“-like”运算符的约束。 我们甚至使用System.Diagnostics.Process方法尝试使用Process.StandardInput.WriteLine(行)逐行编写脚本,但随后PowerShell挂起。

任何指向此问题的指针都将受到高度赞赏。

在使用System.Diagnostics.Process时,我使用了类似的东西:

                ProcessStartInfo processStartInfo = new ProcessStartInfo();
                processStartInfo.UseShellExecute = false;
                processStartInfo.RedirectStandardError = true;
                processStartInfo.RedirectStandardOutput = true;
                processStartInfo.FileName = "powershell.exe";
                processStartInfo.Arguments = <ScriptContent>;
                Process powerShellProc = new Process();
                powerShellProc.StartInfo = processStartInfo;
                powerShellProc.Start();

                string successMessage = powerShellProc.StandardOutput.ReadToEndAsync().Result;
                string errorMessage = powerShellProc.StandardError.ReadToEndAsync().Result;
                powerShellProc.WaitForExit();

其中, ScriptContent-是上面的powershell脚本。

而不是喜欢,甚至尝试使用startwith,但后来也是相同的结果。但是使用PowerShell控制台或iSE,它可以很好地工作。

1 个答案:

答案 0 :(得分:0)

回答可能已经太晚了:)

你不应该调用powerShellProc.StandardOutput.ReadToEndAsync()。在进程实际完成之前的结果。您可以使用How to capture process output asynchronously in powershell?

中的Invoke-Executable函数

以下订单正在运作

   $outTask = $oProcess.StandardOutput.ReadToEndAsync();
    $errTask = $oProcess.StandardError.ReadToEndAsync();
    $bRet=$oProcess.WaitForExit($TimeoutMilliseconds)
    $outText = $outTask.Result;
    $errText = $errTask.Result;