【问题标题】:Powershell: system-diagnostics-processstartinfo hangs, reason unknownPowershell:system-diagnostics-processstartinfo 挂起,原因未知
【发布时间】:2022-12-10 07:18:19
【问题描述】:

深受 Stackoverflow 上其他问题的影响,我最终使用这种方法从我的 Powershell 脚本启动进程

function global:system-diagnostics-processstartinfo {
[CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]
param
(
    [Parameter(Mandatory=$True,HelpMessage='Full path to exectuable')]
    [Alias('exectuable')]
    [string]$exe,
    [Parameter(Mandatory=$True,HelpMessage='All arguments to be sent to exectuable')]
    [Alias('args')]
    [string]$arguments
)

if (!(Test-Path $exe)) {
    $log.errorFormat("Did not find exectuable={0}, aborting script", $exe)
    exit 1  
}

$log.infoFormat("Start exectuable={0} with arguments='{1}'", $exe, $arguments)
$processStartInfo = New-Object System.Diagnostics.ProcessStartInfo($exe)
$processStartInfo.FileName = $exe
$processStartInfo.RedirectStandardError = $true
$processStartInfo.RedirectStandardOutput = $true
$processStartInfo.UseShellExecute = $false
$processStartInfo.Arguments = $arguments
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $processStartInfo
$log.info("Start exectuable and wait for exit")
$p.Start() | Out-Null

#$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
$log.infoFormat("exectuable={0}  stdout: {1}", $exe, $stdout)
$log.debugFormat("exectuable={0} stderr: {1}",  $exe,$stderr)
$global:ExitCode = $p.ExitCode
$log.debugFormat("exectuable={0} Exitcode: {1}", $exe, $p.ExitCode)

return $stdout
}

非常简单,添加了一些日志记录等。它适用于我当前的所有用例,但不包括一个。我创建了一个脚本,用于将我们的 Confluence 生产实例的数据库转储复制到我们的测试服务器。然后它使用上述方法删除现有数据库,一切正常。但实际的恢复只是永远挂起。所以现在我必须退出脚本,然后手动运行以下命令

d:\postgresql\bin\pg_restore.exe -U postgres -d confluencedb -v -1 d:\temp\latest-backup.pgdump

这需要一些时间并且有相当多的输出。这让我相信一定有以下任何一个导致了这个问题

  • 输出量导致缓冲区溢出并停止脚本
  • 需要很多时间

哪位有类似经历的可以帮我解决一下。它将能够安排导入,而不必像今天那样手动执行。

【问题讨论】:

    标签: powershell processstartinfo


    【解决方案1】:

    我必须在处理后立即执行以下操作。开始:

    # Capture output during process execution so we don't hang
    # if there is too much output.
    do
    {
        if (!$process.StandardOutput.EndOfStream)
        {
            [void]$StdOut.AppendLine($process.StandardOutput.ReadLine())
        }
        if (!$process.StandardError.EndOfStream)
        {
            [void]$StdErr.AppendLine($process.StandardError.ReadLine())
        }
    
        Start-Sleep -Milliseconds 10
    }
    while (!$process.HasExited)
            
    # Capture any standard output generated between our last poll and process end.
    while (!$process.StandardOutput.EndOfStream)
    {
        [void]$StdOut.AppendLine($process.StandardOutput.ReadLine())
    }
        
    # Capture any error output generated between our last poll and process end.
    while (!$process.StandardError.EndOfStream)
    {
        [void]$StdErr.AppendLine($process.StandardError.ReadLine())
    }
    
    # Wait for the process to exit.
    $process.WaitForExit()
    LogWriteFunc ("END process: " + $ProcessName)
    
    if ($process.ExitCode -ne 0)
    {
        LogWriteFunc ("Error: Script execution failed: " + $process.ExitCode )
        $FuncResult = 1
    }
    
    # Log and display any standard output.
    if ($StdOut.Length -gt 0)
    {
        LogWriteFunc ($StdOut.ToString())
    }
        
    # Log and display any error output.
    if ($StdErr.Length -gt 0)
    {
        LogWriteFunc ($StdErr.ToString())
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-30
      • 2019-04-30
      • 1970-01-01
      • 1970-01-01
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      相关资源
      最近更新 更多