PostMessage не работает с окном консоли, вывод которого перенаправляется и читается асинхронно

У меня есть приложение с графическим интерфейсом, которое читает консольное приложение, которое показывает вывод и ждет выхода F4, мне удалось запустить процесс с помощью:

p.StartInfo.FileName = "consoleapp.exe";
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.RedirectStandardInput = false;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = false; 
p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(ConsoleOutputHandler);
p.Start();
p.BeginOutputReadLine();

И я могу отправить F4, используя:

PostMessage(p.MainWindowHandle, (uint)WM_KEYUP, (IntPtr) Keys.F4, (IntPtr) 0x3E0001 );

Все работает нормально, пока я не перенаправляю StandardOutput с помощью:

p.StartInfo.RedirectStandardOutput = true;

Таким образом, PostMessage по-прежнему отправляет событие (проверено Spy++), но консольное приложение его не распознает.

Изменение «RedirectStandardInput» не дало никаких результатов.

Какие-нибудь мысли?


person Nilson Morais    schedule 24.01.2013    source источник
comment
попробуйте просмотреть этот пост Stackoverflow для рабочего решения, надеюсь, что оно решит вашу проблему stackoverflow.com/ вопросы/1145969/   -  person MethodMan    schedule 25.01.2013
comment
На самом деле у меня нет проблем с чтением stdout, просто PostMessage, который перестает работать, когда я перенаправляю вывод. Спасибо за комментарий.   -  person Nilson Morais    schedule 25.01.2013
comment
Я попытался перенаправить и записать в стандартный ввод с помощью StreamWriter, но это тоже не сработало.   -  person Nilson Morais    schedule 25.01.2013


Ответы (2)


Я это сделал!

Я запускаю это при запуске моего приложения:

AllocConsole();
uint codepage = GetACP();
SetConsoleOutputCP(codepage);

IntPtr handleconsole = new IntPtr();
handleconsole = GetConsoleWindow();

затем создайте процесс с..

p.StartInfo.RedirectStandardOutput = true; 
p.StartInfo.RedirectStandardInput = false; 
p.StartInfo.RedirectStandardError = true;

Это создает консоль для моего приложения, после чего каждый запущенный процесс наследует эту консоль, поэтому ее легко читать stdout, даже если вы вызываете ShowWindow, чтобы скрыть ее.

После этого я создал INPUT_RECORD для отправки клавиши F4:

inHandle = GetStdHandle(STD_INPUT_HANDLE);
record[0].EventType = KEY_EVENT;
record[0].KeyEvent.bKeyDown = true;
record[0].KeyEvent.dwControlKeyState = 0;
record[0].KeyEvent.wRepeatCount = 1;
record[0].KeyEvent.wVirtualKeyCode = VirtualKeys.F4;
record[0].KeyEvent.wVirtualScanCode = MapVirtualKey(VK_F4, MAPVK_VK_TO_VSC);

record[1].EventType = KEY_EVENT;
record[1].KeyEvent.bKeyDown = false;
record[1].KeyEvent.dwControlKeyState = 0;
record[1].KeyEvent.wRepeatCount = 1;
record[1].KeyEvent.wVirtualKeyCode = VirtualKeys.F4;
record[1].KeyEvent.wVirtualScanCode = MapVirtualKey(VK_F4, MAPVK_VK_TO_VSC);

WriteConsoleInput(inHandle, record, 1, out written);
person Nilson Morais    schedule 08.02.2013

Вы, вероятно, не хотите использовать PostMessage для этого. Поскольку ваша цель — консольное приложение, вы должны записать ключ в его входной буфер, используя Win32 API WriteConsoleInput через p/invoke, в следующих строках:

p.StartInfo.RedirectStandardInput = true ;
// the rest of your code 

int written ;
var record = new KEY_INPUT_RECORD
{
    EventType = KEY_EVENT,
    bKeyDown  = true,
    wVirtualKeyCode = VK_F4,
    // maybe set other members, use ReadConsoleInput 
    // to get a sample and hard-code it
    // you might even use a byte array representation
    // of the input record, since you only need one key
} ;

WriteConsoleInput (((FileStream)p.StandardInput.BaseStream).SafeFileHandle,
    ref record, 1, out written) ;
person Anton Tykhyy    schedule 25.01.2013
comment
Я попробовал WriteConsoleInput, но пока не работает, у меня есть дескриптор консоли, и в результате говорится, что он написал в консоли, но не получил ответа от ConsoleApp. Я буду пытаться. Спасибо за ответ. - person Nilson Morais; 28.01.2013