Using AttachConsole, while the process I've at

2019-03-19 20:50发布

问题:

Using AttachConsole, while the process I've attached with is running and spewing, I can still type and run other commands.

My program runs in either a form, or from command line. If started with arguments it runs in the command window. I use AttachConsole(-1) to attach my process to command window I called from. It works great, I get all my output spew from my process.

However, the console still processes user input from the keyboard, whatever I type, for instance, if I type 'cls' and hit enter, the output will be wiped. How can I block user input to the console while the process is running?

回答1:

This may not be elegant based on what you are doing, but do a Kill() on the console after attaching it and it will continue to get output from your other process. Example Windows Forms code below, add your own bells and whistles:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
   internal static class Program
    {
    [DllImport("kernel32", SetLastError = true)]
    private static extern bool AttachConsole(int dwProcessId);

    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

    [STAThread]
    private static void Main(string[] args)
    {
        IntPtr ptr = GetForegroundWindow();

        int u;

        GetWindowThreadProcessId(ptr, out u);

        Process process = Process.GetProcessById(u);

        AttachConsole(process.Id);

        process.Kill();

        Application.EnableVisualStyles();

        Application.SetCompatibleTextRenderingDefault(false);

        Application.Run(new Form1());
    }
}
}


回答2:

I found a little cleaner solution is just to send an extra "Enter" to the console after your program exits:

[STAThread]
public static int Main(string[] args)
{
    try
    {
        AttachConsole(ATTACH_PARENT_PROCESS);
        ...
        ...
    }
    catch (Exception eCatchAll)
    {
        ShowHelpCommand.ShowHelp(eCatchAll.ToString());     
        return (int) ConsoleReturnCode.UnexpectedError;
    }
    finally
    {
        ConsoleNewLine();
    }
}

private static void ConsoleNewLine()
{
    try
    {
        // When using a winforms app with AttachConsole the app complets but there is no newline after the process stops. This gives the newline and looks normal from the console:
        SendKeys.SendWait("{ENTER}");
    }
    catch (Exception e)
    {
        Debug.Fail(e.ToString());
    }
}


回答3:

Not quite sure about this but is AllocConsole instead of AttachConsole not a more easy approach for this problem?