1

我正在编写一个带有 GUI 的小型 PowerShell 脚本,用于处理 Ping 命令。目前,我有脚本读取用户的输入以确定要 ping 的 IP 地址/URL,然后将输出显示到富文本框。

但是,目前,COMPLETES 命令会立即写入整个输出。我希望它实时显示每一行输出 - 使其看起来与在 shell 中运行命令的方式相同。

当按下 Ping 按钮时,会调用以下函数(我认为这就是问题所在):

Function FNPing {
    $OutputBox.Text = "Please Wait..."
    $ping = ping ($InputBox.text)
    $OutputBox.Text = ""
    foreach ($line in $ping) {
        $OutputBox.Appendtext($line+[char]13+[char]10)
    }
}

我想这个问题可能可以在 ForEach 语句中解决,我只是不知道该怎么做!感谢所有帮助!

4

2 回答 2

2

我会尝试使用test-connectioncmdlet。问题是 ping 一个外部 exe,所以当它完成时,你得到的只是一团文本。在运行时获得 ping 输出的唯一方法是使用start-process和重定向输出(这很混乱)。

test-connection你不会得到一个漂亮的总结,但信息都在那里。对于摘要信息,measure-object可以提供帮助。下面是 ping 输出的模仿,应该可以帮助您入门:

function fnping {
    $outputBox.Text = "Please Wait..."
    $count = 4
    $results = test-connection $inputbox.Text -count $count | foreach { $outputBox.AppendText("Reply from $($_.ProtocolAddress): bytes=$($_.ReplySize) time=$($_.ResponseTime)ms TTL=$($_.TimeToLive)`r`n"); $_ }
    $summary = $results | measure-object -Property ResponseTime -Average -Minimum -Maximum
    $lost = $count - $summary.Count
    $percentLost = $lost * 100.0 / $count
    $outputBox.AppendText("Packets: Sent = $count, Received = $($summary.Count), Lost = $lost ($($percentLost)% loss)`r`n")
    $outputBox.AppendText("Minimum = $($summary.Minimum)ms, Maximum = $($summary.Maximum)ms, Average = $($summary.Average)ms`r`n")
}

编辑

其实我的立场是正确的。将结果分配给变量 ( $ping) 会导致 powershell 等待输出流关闭。您可以轻松地做您想做的事,使用foreach-object. 在这里,我使用一个小的辅助函数在将输出框写入框之前清除输出框:

function WriteEach-Object() { 
    param(
      [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
      [object[]]$inputs
    )  

    begin { $outputBox.Text = "" } 
    process { $inputs | foreach { $outputBox.AppendText($_) } } 
    end { $outputBox.AppendText("`r`n") } 
}

function fnping() {
    $outputBox.Text = "Please Wait..."
    ping $inputBox.Text | writeeach-object
}
于 2013-09-20T09:23:33.010 回答
0

您需要添加 BEGIN {} PROCESS {} 和 END {} 语句来控制函数的工作方式。如果没有给出,Powershell 假定所有内容都在 END {} 语句中,一次性处理所有内容。

变成这样

Function FNPing {
  BEGIN {
  }

  PROCESS {
     $OutputBox.Text = "Please Wait..."
     $ping = ping ($InputBox.text)
     $OutputBox.Text = ""
     foreach ($line in $ping) {
         $OutputBox.Appendtext($line+[char]13+[char]10)
     }
  }

  END {
  }
}

应该做的伎俩。或者,您可以替换FunctionFilter,假设代码位于PROCESS {}块中。

欲了解更多信息:http ://technet.microsoft.com/en-us/magazine/hh413265.aspx

于 2013-09-20T08:04:27.400 回答