Существует принципиальная разница между стандартным входом дочернего процесса и консолью, к которой он подключен. Интерпретатор команд в интерактивном режиме ожидает разговора либо с консолью или с каналом / файлом в качестве стандартного ввода, и он меняет свое поведение в соответствии с тем, которое находит. Для канала / файла он просто вызывает функцию ReadFile()
. Однако для консоли она получает ввод через ReadConsoleInput()
, где не буквенно-цифровые ключи распознаются по их кодам виртуальных клавиш.
См., Например, функцию ReadCommand()
в ReactOS CMD
.
Если вы записываете байт со значением 9 по конвейеру на стандартный ввод процесса, это то, что он увидит после вызова ReadFile()
. Но это не будет восприниматься как нажатие клавиши Tab , потому что (для начала) оно не одно; это просто значение байта 9, идущее вниз по трубе. Кроме того, редактирование командной строки, которое выполняет интерпретатор команд в интерактивном режиме, происходит только тогда, когда стандартный ввод определяется как консоль, а не когда это канал или файл. Интерпретатор команд использует ReadConsoleInput()
, который не читает буферы байтов, а читает последовательности INPUT_RECORDs
; и, таким образом, вам нужно WriteConsoleInput()
для этой консоли обрабатывать соответствующую INPUT_RECORD
, имитирующую клавишу Tab , если вы хотите, чтобы интерпретатор команд видел нажатие клавиши Tab во входном потоке.
Конечно, поскольку вы установили StartInfo.RedirectStandardInput
на true
, под крышками .NET подключил стандартный ввод процесса интерпретатора команд к каналу; и поэтому интерпретатор команд просто вызывает ReadFile()
, без какого-либо интерактивного редактирования командной строки, как если бы его стандартный ввод был консолью. Даже если бы вы могли найти и открыть дескриптор консоли процесса интерпретатора команд и записать INPUT_RECORD
для клавиши Tab , интерпретатор команд читает канал для своего стандартного ввода и игнорирует его консоль.
Если вы хотите, чтобы интерпретатор команд работал так же, как если бы он разговаривал с консолью, редактировал командную строку и все такое, вы должны запустить процесс со стандартным вводом в качестве консоли , чья ручку, которую вы должны (затем) получить, чтобы имитировать нажатия клавиш с помощью WriteConsoleInput()
. Это довольно сложно в .NET.