Консольное приложение перенаправления ввода C# не работает
У меня интересная ситуация. Я пытаюсь запустить программу из командной строки и по какой-то причине не могу программно перенаправить ее ввод. Исполняемый файл, который я запускаю, называется. Spideroakone.exe. Этот исполняемый файл запрашивает пароль. Когда я набираю пароль, скажем, что пароль "asd", я действительно могу видеть то, что я печатаю, в виде простого текста. Я получаю сообщение об ошибке:
'asd' is not recognized as an internal or external command ...
Если я запускаю исполняемый файл так:
cmd /c Spideroakone.exe
затем снова я вижу то же самое, что меня просят ввести пароль. Затем я набираю asd. Но я не вижу, что я печатаю, пароль работает, и ошибки нет.
Теперь я хочу написать приложение, которое будет запускать Spideroak.exe и передавать пароль на стандартный ввод. Однако из-за странного поведения Spideroak я не могу передать на него какой-либо стандартный ввод или прочитать стандартный вывод. Когда я пытаюсь это сделать, мое приложение блокируется командой writeline. Я бы ожидал увидеть слово "Пароль:" в stdout. Я пробовал некоторые асинхронные примеры и многопоточность, но это не работает. Стандартный выходной буфер всегда пуст. Интересно, что это за текст, который я вижу "Пароль:", если он не записан в стандартный вывод, где он написан?
это код, который я использую. Какие блоки на ReadToEnd()
линия. Этот точный код прекрасно работает с консольным приложением, которое я сделал, поэтому я думаю, что исполняемый файл, который я пытаюсь выполнить, написан странным образом, но в окне командной строки он работает нормально:
Process myProcess = new Process();
myProcess.StartInfo.FileName = @"c:\windows\system32\cmd.exe";
myProcess.StartInfo.Arguments = @"/c ""C:\Program Files\SpiderOakONE\SpiderOakONE.exe"" --headless";
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.Start();
string s = myProcess.StandardOutput.ReadToEnd();
myProcess.WaitForExit();
Это скриншот точного окна отладки и строки, на которой оно блокируется:
Вот что я вижу в окне командной строки:
1 ответ
Ну, никто не ответил, и в то же время я нашел ответ. Я не нашел точной причины, по которой stdout и stdin не работают, но я прочитал статью о том, что кто-то еще жаловался на то, что старые программы, написанные на C с использованием getch(), будут вести себя так. Я хотел сделать это более красиво, но это то, что я придумал. В основном отправка нажатий клавиш в окно консоли. Я не был уверен, сработает ли это, потому что я запускаю процесс в планировщике задач, и визуальное окно не создано, но оно работает нормально.
Я запускаю процесс в отдельном потоке:
new Thread(() =>
{
Process myProcess = new Process();
myProcess.StartInfo.FileName = @"c:\windows\system32\cmd.exe";
myProcess.StartInfo.Arguments = @"/c ""C:\Program Files\SpiderOakONE\SpiderOakONE.exe"" --headless";
myProcess.StartInfo.UseShellExecute = false;
myProcess.Start();
myProcess.WaitForExit();
}).Start();
Затем я перечисляю все окна:
EnumWindows(EnumTheWindows, IntPtr.Zero);
Затем я ищу окно своего процесса и отправляю на него нужные нажатия клавиш. Сон между необходим, без него не работает. Пример пароля, который я отправляю: "asd"
private static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
{
uint pidCurWindow;
uint CurWindowThreadId = GetWindowThreadProcessId(hWnd, out pidCurWindow);
int CurrentPID = System.Diagnostics.Process.GetCurrentProcess().Id;
if (pidCurWindow == CurrentPID)
{
Thread.Sleep(50);
PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('a'), 0);
Thread.Sleep(50);
PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('s'), 0);
Thread.Sleep(50);
PostMessage(hWnd, WM_KEYDOWN, VkKeyScan('d'), 0);
Thread.Sleep(50);
PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 1);
Thread.Sleep(50);
}
return true;
}
Я надеюсь, что это поможет кому-то сэкономить время.