我使用
创建一个子控制台应用程序_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");
最佳答案
子进程的标准输入与其附加的控制台之间存在根本区别。交互模式下的命令解释器期望与控制台对话或与管道/文件对话作为其标准输入,并且它会更改其行为以匹配它的行为发现。对于管道/文件,它只是简单地调用 ReadFile()
功能。然而,对于控制台,它通过 ReadConsoleInput()
接收输入。 ,其中非字母数字键可通过其虚拟键代码进行识别。
请参阅ReadCommand()
以 ReactOS CMD
中的函数为例。
如果您通过管道将一个值为 9 的字节写入进程的标准输入,那么它将通过调用 ReadFile()
看到该内容。但它不会将其视为 Tab 按键,因为(对于初学者来说)它不是一个;它只是来自管道的字节值 9。此外,命令解释器在交互模式下执行的命令行编辑仅在检测到标准输入是控制台时发生,而不是在它是管道或文件时发生。命令解释器使用 ReadConsoleInput()
,它不读取字节缓冲区,而是读取 INPUT_RECORDs
的序列。 ;因此你必须 WriteConsoleInput()
如果您希望命令解释器在其输入流中看到 Tab 按键,则向该控制台处理适当的 INPUT_RECORD
模拟 Tab 键。 p>
当然,由于您已将 StartInfo.RedirectStandardInput
设置为 true
,因此 .NET 在幕后已将命令解释器进程的标准输入连接到管道;因此命令解释器只是调用 ReadFile(),而不进行任何交互式命令行编辑,就像它的标准输入是控制台一样。即使您可以找到并打开命令解释器进程控制台的句柄,并为它的 Tab 键写入 INPUT_RECORD
,命令解释器也会读取管道它的标准输入,并忽略它的控制台。
如果您希望命令解释器的行为就像与控制台对话、命令行编辑等一样,您必须生成进程并将其标准输入作为控制台,您必须(然后)获取其句柄,以便可以使用 WriteConsoleInput()
模拟按键。这在 .NET 中相当困难。
关于.net - 将 TAB 发送到子控制台 (Windows),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/740329/