Powershell:系统诊断-进程启动信息挂起,原因未知

gkl3eglg  于 2022-12-29  发布在  Shell
关注(0)|答案(1)|浏览(129)

受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生产示例的数据库转储复制到我们的测试服务器。然后它使用上述方法删除现有数据库。一切正常。2但是实际的恢复只是永远挂起。3所以现在我必须退出脚本,然后手动运行下面的命令

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

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

  • 输出量会导致缓冲区溢出并暂停脚本
  • 要花很多时间

任何有类似经验的人谁可以帮助我解决这个问题。它将使计划导入,而不必像今天这样手动操作。

a8jjtwal

a8jjtwal1#

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

# 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())
}

相关问题