Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Can';使用Win32 ReadConsoleOutput()捕获telnet.exe输出_C#_.net_Windows_Winapi - Fatal编程技术网

C# Can';使用Win32 ReadConsoleOutput()捕获telnet.exe输出

C# Can';使用Win32 ReadConsoleOutput()捕获telnet.exe输出,c#,.net,windows,winapi,C#,.net,Windows,Winapi,有人能解释为什么我发现用Windows函数ReadConsoleOutput无法捕获telnet.exe的输出吗 我通过C#interop调用它。 下面是我正在使用的类 public static class ConsoleReader { public static IEnumerable<string> ReadFromBuffer(short x, short y, short width, short height) { IntPtr bu

有人能解释为什么我发现用Windows函数ReadConsoleOutput无法捕获telnet.exe的输出吗

我通过C#interop调用它。 下面是我正在使用的类

  public static class ConsoleReader
{
    public static IEnumerable<string> ReadFromBuffer(short x, short y, short width, short height)
    {
        IntPtr buffer = Marshal.AllocHGlobal(width * height * Marshal.SizeOf(typeof(CHAR_INFO)));
        if (buffer == null)
            throw new OutOfMemoryException();

        try
        {
            COORD coord = new COORD();
            SMALL_RECT rc = new SMALL_RECT();
            rc.Left = x;
            rc.Top = y;
            rc.Right = (short)(x + width - 1);
            rc.Bottom = (short)(y + height - 1);

            COORD size = new COORD();
            size.X = width;
            size.Y = height;

            const int STD_OUTPUT_HANDLE = -11;
            if (!ReadConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE), buffer, size, coord, ref rc))
            {
                // 'Not enough storage is available to process this command' may be raised for buffer size > 64K (see ReadConsoleOutput doc.)
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            IntPtr ptr = buffer;
            for (int h = 0; h < height; h++)
            {
                StringBuilder sb = new StringBuilder();
                for (int w = 0; w < width; w++)
                {
                    CHAR_INFO ci = (CHAR_INFO)Marshal.PtrToStructure(ptr, typeof(CHAR_INFO));
                    char[] chars = Console.OutputEncoding.GetChars(ci.charData);
                    sb.Append(chars[0]);
                    ptr += Marshal.SizeOf(typeof(CHAR_INFO));
                }
                yield return sb.ToString();
            }
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct CHAR_INFO
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] charData;
        public short attributes;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct COORD
    {
        public short X;
        public short Y;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct SMALL_RECT
    {
        public short Left;
        public short Top;
        public short Right;
        public short Bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct CONSOLE_SCREEN_BUFFER_INFO
    {
        public COORD dwSize;
        public COORD dwCursorPosition;
        public short wAttributes;
        public SMALL_RECT srWindow;
        public COORD dwMaximumWindowSize;
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool ReadConsoleOutput(IntPtr hConsoleOutput, IntPtr lpBuffer, COORD dwBufferSize, COORD dwBufferCoord, ref SMALL_RECT lpReadRegion);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr GetStdHandle(int nStdHandle);
}

因为telnet不会写入标准输出。它可以使用
-f
参数将其输出重定向到文件:我不确定/f是否接受
con
作为文件。您知道它在哪里写入以及如何捕获其输出吗?作为最后的手段,我可能会将正确的Windows事件拼凑在一起,选择全部并复制到剪贴板或类似的怪事。您可以为
-f
选择任何文件,因此
-fc:\temp\mylog.txt
可以工作…我不尝试记录会话的输出。我需要能够与telnet应用程序交互-通过发送输入(我可以通过模拟击键来实现),并通过实时读取其输出。使用
-fcon
(或
-fcon:
)进行尝试,并使用您当前的位来查看它是否会运行。
        Process p = new Process();
        ProcessStartInfo psi = new ProcessStartInfo();
        psi.FileName = @"telnet";
        psi.UseShellExecute = false;

        p.StartInfo = psi;
        p.Start();

        while (true) 
        {
            Thread.Sleep(100);
            string[] consoleContent = ConsoleReader.ReadFromBuffer(0, 0, 150, 100).ToArray();
        }