Используя AttachConsole, в то время как процесс, с которым я подключился, работает и извергает, я все еще могу вводить и запускать другие команды

используя AttachConsole, в то время как процесс, который я подключил, работает и извергает, я все еще могу вводить и запускать другие команды.

моя программа работает либо в форме, либо из командной строки. Если он запущен с аргументами, он запускается в окне команды. Я использую AttachConsole (-1) для присоединения моего процесса к командному окну, из которого я звонил. Он отлично работает, я получаю все свои выходные данные из моего процесса.

однако консоль по-прежнему обрабатывает пользовательский ввод с клавиатуры, независимо от того, введите, например, если я наберу " cls " и нажму enter, вывод будет стерт. Как заблокировать пользовательский ввод в консоль во время выполнения процесса?

3 ответов


это может быть не элегантно на основе того, что вы делаете, но сделайте Kill() на консоли после ее присоединения, и она будет продолжать получать вывод из вашего другого процесса. Пример кода Windows Forms ниже, добавьте свои собственные колокола и свистки:

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

Я нашел немного более чистое решение - просто отправить дополнительный "ввод" на консоль после выхода вашей программы:

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

Не совсем уверен в этом, но является ли AllocConsole вместо AttachConsole не более простым подходом к этой проблеме?