使用[Console] :: ReadLine()时,不会接收到管道到PowerShell.exe的文本。 [英] Text piped to PowerShell.exe isn't received when using [Console]::ReadLine()

查看:517
本文介绍了使用[Console] :: ReadLine()时,不会接收到管道到PowerShell.exe的文本。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 
> ping localhost | powershell -NonInteractive -NoProfile -Cdo {$ line = [Console] :: ReadLine();(''+(Get-Date -f'HH:mm
:ss')+ $ line) -Host;} while($ line -n​​e $ 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

正常情况下,从Vista64ping localhost看起来像这样,所以上面的输出中缺少很多数据:

 

Pinging WORLNTEC02.bnysecurities.corp.local [:: 1] from :: 1 with 32 bytes of data:
回复:: 1:time< 1ms
回复:: 1 :time< 1ms
从:: 1回复::时间< 1ms
从:: 1回复时间< 1ms

Ping统计信息为:: 1:
:Sent = 4,Received = 4,Lost = 0(0%loss),
大约往返时间,单位为毫秒:
最小= 0ms,最大= 0ms,平均= 0ms

但是从C#使用相同的API接收发送到该进程的所有数据(不包括一些换行符差异)。代码:

 命名空间ConOutTime {
class Program {
static void Main(string [] args){
string s;
while((s = Console.ReadLine())!= null){
if(s.Length> 0)//不为空行写时间
Console.WriteLine ({0:HH:mm:ss} {1},DateTime.Now,s);
}
}
}
}



 
00:44:30从32位数据中读取:: 1中的WORLNTEC02.bnysecurities.corp.local [:: 1] :
00:44:30回复:: 1:时间< 1ms
00:44:31回复:: 1:时间< 1ms
00:44:32回复从:: 1:时间<1ms
00:44:33回复:: 1:时间< 1ms
00:44:33 Ping统计为:: 1:
00:44:33数据包:发送= 4,接收= 4,丢失= 0(0%损失),
00:44:33大约往返时间以毫秒为单位:
00:44:33最小= 0ms, 0ms,Average = 0ms

因此,如果从PowerShell中调用相同的API而不是C#,StdIn的许多部分都会被'eaten'。是PowerShell主机从StdIn读取字符串,即使我没有使用'PowerShell.exe -Command - '?

解决方案

可以使用PowerShell中的 $ input 枚举器来访问管道传入程序的数据。我也发现 [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回复from 1:time< ; 1ms
07:31:54回复:: 1:时间< 1ms
07:31:55回复:: 1:时间< 1ms
07:31:55
07:31:55 Ping统计信息:: 1:
07:31:55数据包:Sent = 4,Received = 4,Lost = 0(0%loss),
07:31:55近似往返时间(毫秒):
07:31:55最小值= 0ms,最大值= 0ms,平均值= 0ms

C:\Users\Me> ping localhost

Pinging Sigmund [:: 1] with 32 bytes of data:
回复:: 1:time< 1ms
回复:: 1:time< 1ms
从:: 1:时间< 1ms
从:: 1回复时间< 1ms

Ping统计信息:: 1:
数据包:Sent = 4,Received = Lost = 0(0%loss),
大约往返时间(毫秒):
最小值= 0ms,最大值= 0ms,平均值= 0ms
pre>

I'm getting itermittent data loss when calling .NET [Console]::ReadLine() to read piped input to PowerShell.exe. In CMD, run:

>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

Normally 'ping localhost' from Vista64 looks like this, so there is a lot of data missing from the output above:


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

But using the same API from C# receives all the data sent to the process (excluding some newline differences). 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);
            } 
        }
    }
}

Output:

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

So, if calling the same API from PowerShell instead of C# many parts of StdIn get 'eaten'. Is the PowerShell host reading string from StdIn even though I didn't use 'PowerShell.exe -Command -'?

解决方案

You can use the $input enumerator in PowerShell to get access to data piped into the program. I also have found that [Console]::ReadLine() somehow does little to nothing. Unknown reasons for that, though.

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

这篇关于使用[Console] :: ReadLine()时,不会接收到管道到PowerShell.exe的文本。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆