1

Ping コマンドを処理する、GUI を使用した小さな PowerShell スクリプトを作成しています。現在、スクリプトでユーザーからの入力を読み取って ping する IP アドレス/URL を決定し、出力をリッチ テキスト ボックスに表示しています。

ただし、現在、コマンド COMPLETES は出力全体を一度に書き込みます。出力の各行をリアルタイムで表示したいので、シェルでコマンドを実行するのと同じように表示されます。

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-connectionコマンドレットを使用してみます。問題は、外部の exe に ping を実行することです。そのため、完了するとテキストの塊だけが得られます。実行中に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 {
  }
}

トリックを行う必要があります。または、コードがブロック内にあると仮定して、 を にFunction置き換えることもできます。FilterPROCESS {}

詳細情報: http://technet.microsoft.com/en-us/magazine/hh413265.aspx

于 2013-09-20T08:04:27.400 に答える