【问题标题】:Send TAB to a child console (windows)将 TAB 发送到子控制台(Windows)
【发布时间】:2009-04-11 15:51:29
【问题描述】:

我用

创建了一个子控制台应用程序
_process = new Process();
_process.StartInfo.FileName = @"cmd.exe";
_process.StartInfo.UseShellExecute = false;
_process.StartInfo.RedirectStandardInput = true;
_process.StartInfo.RedirectStandardOutput = true;
_process.StartInfo.CreateNoWindow = true;

_proccess.Start();

现在我可以去 c:\aaa

_process.StandardInput.Write("cd c:\\aaa\xD\xA");

但通常用户可以键入 c:\ + TAB + ENTER。我该怎么做?这不起作用:

_process.StandardInput.Write("cd c:\\\0x9\xD\xA");

【问题讨论】:

    标签: .net console tab-completion


    【解决方案1】:

    子进程的标准输入和它所连接的控制台之间有一个根本的区别。交互模式下的命令解释器期望将 either 与控制台 与管道/文件作为其标准输入进行对话,并且它会更改其行为以匹配它发现。对于管道/文件,它只是简单地调用ReadFile() 函数。然而,对于控制台,它通过ReadConsoleInput() 接收输入,其中非字母数字键可通过其虚拟键码识别。

    有关示例,请参阅 ReactOS CMD 中的 ReadCommand() 函数。

    如果您将一个值为 9 的字节沿管道写入进程的标准输入,这就是它从调用 ReadFile() 时看到的内容。但它不会将其视为 Tab 按键,因为(对于初学者)它不是一个;它只是一个字节值 9 从管道中传下来。此外,命令解释器在交互模式下执行的命令行编辑仅在检测到标准输入是控制台时发生,而不是在它是管道或文件时发生。命令解释器使用ReadConsoleInput(),它不读取字节缓冲区,而是读取INPUT_RECORDs的序列;因此,如果您希望命令解释器在其输入流中看到 Tab 按键,则必须 WriteConsoleInput() 到该控制台处理适当的 INPUT_RECORD 模拟 Tab 键.

    当然,既然您已将StartInfo.RedirectStandardInput 设置为true,那么在幕后.NET 已将命令解释程序进程的标准输入连接到管道;所以命令解释器只是调用ReadFile(),而不做任何交互式命令行编辑,就像它的标准输入是一个控制台一样。即使您可以找到并打开命令解释器进程控制台的句柄,并为 Tab 键写入INPUT_RECORD,命令解释器仍在为其标准输入读取管道,并且忽略它的控制台。

    如果您希望命令解释器像与控制台对话、命令行编辑等等一样工作,您必须生成进程将其标准输入作为控制台,您必须(然后)获得其句柄,以便您可以使用WriteConsoleInput() 模拟按键。这在 .NET 中相当困难。

    【讨论】:

      【解决方案2】:

      使用 Windows API 怎么样?

      using System.Runtime.InteropServices;
      //...
      [DllImport("user32.dll")]
      private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
      private const int WM_CHAR = 0x0102;
      private const int VK_TAB = 0x9;
      private const int VK_RETURN = 0xD;
      //...
      SendMessage(_process.Handle, WM_CHAR, new IntPtr(VK_TAB), new IntPtr(0));
      SendMessage(_process.Handle, WM_CHAR, new IntPtr(VK_RETURN), new IntPtr(0));
      

      但是根据Kevin Montrose's answer here,这并不总是有效。

      【讨论】:

        猜你喜欢
        • 2014-03-09
        • 2012-06-09
        • 2016-07-02
        • 1970-01-01
        • 2013-02-06
        • 2011-04-28
        • 2020-11-04
        • 2013-06-19
        • 1970-01-01
        相关资源
        最近更新 更多