2

I Have a GUI app that reads a console application that shows output and waits for F4 to exit, I've managed to launch the process with:

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();

And I can send F4 using:

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

Everything works fine until I redirect StandardOutput with:

p.StartInfo.RedirectStandardOutput = true;

That way PostMessage still send the event (checked by Spy++), but the console app doesn't recognize it.

Changing "RedirectStandardInput" didn't make any progress.

Any thoughts?

4

2 回答 2

1

我做的!

我在我的应用程序启动时运行它:

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

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

然后用..创建进程

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

这为我的应用程序创建了一个控制台,在此之后每个启动的进程都会继承该控制台,因此即使您调用 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);
于 2013-02-08T17:57:05.563 回答
0

你可能不想用PostMessage这个。由于您的目标是一个控制台应用程序,您应该使用 Win32 API 通过 p/invoke 将密钥写入其输入缓冲区WriteConsoleInput,如下所示:

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) ;
于 2013-01-25T15:05:37.097 回答