代码之家  ›  专栏  ›  技术社区  ›  yzorg

使用[Console]::ReadLine()时未收到通过管道传输到PowerShell.exe的文本

  •  5
  • yzorg  · 技术社区  · 15 年前

    调用.NET时,我的数据丢失了 [Console]::ReadLine() 读取到PowerShell.exe的管道输入。在CMD中,运行:

    >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
    

    通常情况下,Vista64中的“ping localhost”看起来是这样的,因此上面的输出中缺少很多数据:

    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
    

    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);
                } 
            }
        }
    }
    

    输出:

    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
    

    因此,如果从PowerShell而不是C调用相同的API,StdIn的许多部分都会被“吃掉”。即使我没有使用“PowerShell.exe-Command-”,PowerShell主机是否仍在从StdIn读取字符串?

    3 回复  |  直到 8 年前
        1
  •  7
  •   Joey Gumbo    15 年前

    $input PowerShell中的枚举器,以访问通过管道传输到程序中的数据。我还发现 [Console]::ReadLine() 不知怎的,什么都没做。但原因不明。

    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
    
        2
  •  1
  •   stej    15 年前

    一个可能的解决方案是:

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

    我为其他问题访客添加它,因为我认为您不使用它有一些原因:)

        3
  •  0
  •   yzorg    15 年前

    我最终从PowerShell内部调用了外部工具,并将管道连接到Out Time advanced函数。。。

    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