为啥我的Windows powershell读取结果有一堆90m

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥我的Windows powershell读取结果有一堆90m相关的知识,希望对你有一定的参考价值。

参考技术A powershell占用内存是很大的。
你使用powershell占用了太多内存就容易使读取结果一堆90m。打开任务管理器清楚进程就行了。
WindowsPowerShell是集成脚本环境的一款主机应用程序,使在一个友好的环境中编写、运行和测试脚本与模块。其语法着色、Tab补齐、可视调试、Unicode遵从以及上下文相关帮助等主要功能,提供丰富的脚本编写体验。

为啥我的 powershell 没有读取我通过网络流发送的内容

【中文标题】为啥我的 powershell 没有读取我通过网络流发送的内容【英文标题】:Why Isn't my powershell reading what I send over the network stream为什么我的 powershell 没有读取我通过网络流发送的内容 【发布时间】:2021-12-31 15:23:06 【问题描述】:

所以我用 C# 创建了一个服务器,它接受一个套接字连接作为 TCP 客户端。

static void Main(string[] args)

    TcpListener listener = new TcpListener(Address, PORT);
    listener.Start();
    var client = listener.AcceptTcpClient();

    Console.WriteLine("Client has connected!");

    while (true)
    
        Console.Write("Powershell Command: ");
        var cmd = Console.ReadLine();
        client.Client.Send(Encoding.ASCII.GetBytes(cmd));
    

我正在尝试使用 Powershell 连接到它,它连接得很好。

$tcpConnection = New-Object System.Net.Sockets.TcpClient($args[0], $args[1])
$tcpStream = $tcpConnection.GetStream()
$reader = New-Object System.IO.StreamReader($tcpStream)
$writer = New-Object System.IO.StreamWriter($tcpStream)

$buffer = new-object System.Byte[] 1024
$encoding = new-object System.Text.AsciiEncoding 

while ($tcpConnection.Connected)

    while ($true)
    
        $rawresponse = $reader.Read($buffer, 0, 1024)
        $rawresponse.Length
        $response = $encoding.GetString($buffer, 0, $rawresponse)  
        Write-Host $response
    


$reader.Close()
$writer.Close()
$tcpConnection.Close()

问题是当我从服务器发送消息时,powershell 会打印出来0 所以只有一个 1 和一个空格。即使我发送字符串"Test"

这是为什么呢?以及当我发送时如何正确地打印出字符串"Test"

【问题讨论】:

你检查过$RawResponse吗?那有多个字符吗?它是否包含发送给它的任何字符? $RawResponse 包含0x04 假设你收到一个完整的数据包,是不现实的。 @JohnA - 即 4 in dec ... 并且似乎与已发送项目的 length 匹配 - Test。这听起来确实像“缓冲区中有 4 个字符”。当您发送“这不是测试”时会发生什么? 【参考方案1】:

您的代码中有几个细微的错误:

缓冲区长度

首先,来自StreamReader.Read(Char[], Int32, Int32) 方法的文档:

返回

Int32

已读取的字符数,如果在流的末尾并且没有读取数据,则为 0。该数字将小于或等于 count 参数,具体取决于数据是否在流中可用。

您的$rawresponse 已经包含写入缓冲区的字符数,因此您不需要使用$rawresponse.Length。但是,为了让您保持警觉,PowerShell 会自动将默认的 LengthCount 属性添加到所有变量(如果它们还没有) - 例如:

PS> $x = 4
PS> $x
4
PS> $x.Length
1
PS> $x.Count
1

所以你输出 PowerShell 的变量“长度”与行 $rawresponse.Length,而不是写入缓冲区的字符数。 (我找不到这种行为的良好参考,但我相信它基本上是为了帮助处理管道中的对象)。

删除.Length,您将显示正确的值。

缓冲区类型

另一个问题是这一行:

$buffer = new-object System.Byte[] 1024

如果我们回到 StreamReader.Read(Char[], Int32, Int32) 的文档,它会说参数是:

public override int Read(char[] buffer, int index, int count);

注意缓冲区是char[],而不是byte[]。如果您在 C# 中尝试此操作,您会遇到编译器错误,但 PowerShell 会尝试提供帮助,并在调用 Read 方法时将您的 byte[] 变量转换为临时的 char[] 变量。但是,它不会将结果转换回来并在之后将其放入原始的byte[] 变量中,因此Read 方法对临时缓冲区所做的任何更改都将丢失。

如果您将代码更改为:

$buffer = new-object System.Char[] 1024

您将获得所需的输出,因为原始缓冲区已传递给 Read 方法:

response = 'test'

缓冲区长度(再次)

顺便说一句,您还应该在循环中读取缓冲区为每个命令,直到Read 返回 0,因为不能保证它会在一次读取中耗尽流。有关示例,请参见上面链接中的代码...

【讨论】:

以上是关于为啥我的Windows powershell读取结果有一堆90m的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的电脑安装SQL server 2008时提示要安装windows powershell

为啥“npm audit”CLI 命令不能从 Windows 10 中的 Powershell 运行?

powershell PowerShell:读取Windows Installer(MSI)数据库的函数

为啥安装sql Server 2008时总是显示windows powershell错误?

为啥 PowerShell(使用 Perl)在简单的打印语句中删除双引号?

使用 cmd.exe 或 PowerShell 或 Python 从 Windows 命名管道中读取