2010-05-25 4 views
5

Ich bekomme itermittent Datenverlust beim Aufrufen .NET [Console]::ReadLine() zu piped Eingabe in PowerShell.exe zu lesen. In CMD läuft:Text piped zu PowerShell.exe wird nicht empfangen, wenn [Console] :: ReadLine()

 
>ping localhost | powershell -NonInteractive -NoProfile -C "do {$line = [Console]::ReadLine(); ('' + (Get-Date -f 'HH:mm 
:ss') + $line) | Write-Host; } while ($line -ne $null)" 
23:56:45time<1ms 
23:56:45 
23:56:46time<1ms 
23:56:46 
23:56:47time<1ms 
23:56:47 
23:56:47 

Normalerweise 'ping localhost' von Vista64 wie folgt aussieht, so gibt es eine Menge von Daten aus der Ausgabe fehlen oben:

 

Pinging WORLNTEC02.bnysecurities.corp.local [::1] from ::1 with 32 bytes of data: 
Reply from ::1: time<1ms 
Reply from ::1: time<1ms 
Reply from ::1: time<1ms 
Reply from ::1: time<1ms 

Ping statistics for ::1: 
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), 
Approximate round trip times in milli-seconds: 
    Minimum = 0ms, Maximum = 0ms, Average = 0ms 

Aber mit der gleichen API von C# empfängt alle an den Prozess gesendeten Daten (mit Ausnahme einiger Zeilenumbrüche). Code:

namespace ConOutTime { 
    class Program { 
     static void Main (string[] args) { 
      string s; 
      while ((s = Console.ReadLine()) != null) { 
       if (s.Length > 0) // don't write time for empty lines 
        Console.WriteLine("{0:HH:mm:ss} {1}", DateTime.Now, s); 
      } 
     } 
    } 
} 

Ausgang:

 
00:44:30 Pinging WORLNTEC02.bnysecurities.corp.local [::1] from ::1 with 32 bytes of data: 
00:44:30 Reply from ::1: time<1ms 
00:44:31 Reply from ::1: time<1ms 
00:44:32 Reply from ::1: time<1ms 
00:44:33 Reply from ::1: time<1ms 
00:44:33 Ping statistics for ::1: 
00:44:33  Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), 
00:44:33 Approximate round trip times in milli-seconds: 
00:44:33  Minimum = 0ms, Maximum = 0ms, Average = 0ms 

Also, wenn die gleiche API von Powershell anstelle von C# viele Teile StdIn 'gegessen' get rufen. Liest der PowerShell-Host eine Zeichenfolge aus StdIn, obwohl ich "PowerShell.exe-Befehl -" nicht verwendet habe?

+0

ich einen Fehler bekam: „Ein Ausdruck nach‚(‘erwartet wurde.“ Wenn ich laufen dies unter PowerShell. Reparieren Sie Ihre Frage, um CMD zu spezifizieren. Ihre Fragen sind voller guter Details (danke!), aber konnten Sie nicht etwas Dinge vereinfachen, indem Sie das "Get-Date" -Bit entfernen? –

+0

Ich bestätige, dass die Ergebnisse sind intermittierend/unzuverlässig.Es scheint auf Geschwindigkeit beruhend.Wenn "ping" durch etwas schneller ersetzt wird ('type foo.txt'), bekomme ich keine Ausgabe.Wenn ich etwas langsam benutze (' copy con') bekomme ich alles –

+0

@JayBazuzi Der Zeitstempel pro Zeile war der einzige Grund, warum ich überhaupt durch Powershell gepumpt habe. ;) – yzorg

Antwort

5

Sie können den Enumerator $input in PowerShell verwenden, um auf Daten zuzugreifen, die an das Programm weitergeleitet werden. Ich habe auch festgestellt, dass [Console]::ReadLine() irgendwie wenig zu nichts macht. Unbekannte Gründe dafür.

C:\Users\Me> ping localhost | powershell -noninteractive -noprofile -c "$input|%{(date -f HH:mm:ss)+' '+$_}" 

07:31:54 
07:31:54 Pinging Sigmund [::1] with 32 bytes of data: 
07:31:54 Reply from ::1: time<1ms 
07:31:54 Reply from ::1: time<1ms 
07:31:54 Reply from ::1: time<1ms 
07:31:55 Reply from ::1: time<1ms 
07:31:55 
07:31:55 Ping statistics for ::1: 
07:31:55  Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), 
07:31:55 Approximate round trip times in milli-seconds: 
07:31:55  Minimum = 0ms, Maximum = 0ms, Average = 0ms 

C:\Users\Me>ping localhost 

Pinging Sigmund [::1] with 32 bytes of data: 
Reply from ::1: time<1ms 
Reply from ::1: time<1ms 
Reply from ::1: time<1ms 
Reply from ::1: time<1ms 

Ping statistics for ::1: 
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), 
Approximate round trip times in milli-seconds: 
    Minimum = 0ms, Maximum = 0ms, Average = 0ms 
+0

guter Trick mit $ input. Wusste nicht, dass es möglich ist, es auf diese Weise zu verwenden, wenn "Pipeline außerhalb des Powershell-Prozesses ist". – stej

+0

@stej: Ich kenne keinen anderen zuverlässigen Weg. Und es ist schrecklich für Code-Golf, da man nur ein Array von Eingabezeilen mit '@ ($ input)' bekommen kann, aber zeilenweise bei Bedarf nicht lesen kann :-( – Joey

+0

@Joey das funktioniert nicht mit hex Konvertierung, Beispiel ''{0: x}' -f $ input'. Können Sie aktualisieren? –

1

Eine mögliche Lösung ist diese:

powershell -NonInteractive -NoProfile -C "ping localhost | % { ('' + (Get-Date -f 'HH:mm:ss') + $_) | Write-Host; }" 

ich es auch für andere Frage Besucher bin hinzufügen, weil ich glaube, Sie einige Gründe hatte, warum Sie nicht verwenden, dass :)

0

Ich reiche meine endgültige Lösung ein, auch wenn es nicht wirklich eine Antwort auf meine erste Frage war. Ich habe versucht, Daten in Powershell aus einer cmd.exe-Umgebung, die eine Reihe von spezialisierten Tools (siehe www.streambase.com) hatte. Schließlich habe ich die Tools in meine Powershell-Umgebung eingefügt.

landete ich den Aufruf des externen Tool aus Powershell und Rohrleitungen zu Out-Time erweiterte Funktion ...

function Out-Time { 
param (
    [parameter(ValueFromPipeline=$true)] 
    $Value, 
    [switch] $OutputEmptyLines=$false) 
process { 
    if (!$OutputEmptyLines -and ($Value -eq $null -or $Value -eq '')) { 
    } 
    else { 
     "{0} {1}" -f @((get-date -Format "HH:mm:ss.ff"), $Value) 
    } 
} 
} 
#test 
#ping localhost | Out-Time; ping localhost | Out-Time -OutputEmpty 
Verwandte Themen