Консольное приложение завершается только при удерживании клавиши во время выполнения пакетного скрипта - PullRequest
2 голосов
/ 28 марта 2019

Я пытаюсь создать консольное приложение C #, которое неоднократно запускает файл .bat и сохраняет вывод в переменную, которая будет изменена позже. Сценарий предназначен для получения открытых TCP-соединений на подключенном устройстве с использованием adb.exe.

Я хочу, чтобы приложение закрывалось при нажатии клавиши Esc (один раз). Для этого я следовал этому ответу и реализовал его так:

Program.cs

static void Main(string[] args)
{
    Console.WriteLine("Press escape to quit");
    do
    {
        while (!Console.KeyAvailable)
        {
            // Console.WriteLine("Application is running");
            RunBatch();
        }
    } while (Console.ReadKey(true).Key != ConsoleKey.Escape);
    Console.WriteLine("While loop was exited");
    Console.ReadLine();
}

static void RunBatch()
{
    Process p = new Process();
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.FileName = @"C:\Dev\Batch\GetTcpConnections.bat";
    p.Start();

    string output = p.StandardOutput.ReadToEnd();

    p.WaitForExit();
    Console.WriteLine(output);
}

GetTcpConnections.bat

@echo off
echo %time%
adb.exe shell cat /proc/net/tcp
timeout /t 1 /nobreak>nul

Ожидаемый результат: консольное приложение выходит из цикла и печатает While loop was exited непосредственно после нажатия Esc . Это работает так, когда я комментирую RunBatch() и не комментирую Console.WriteLine("Application is running". Однако, когда я запускаю пакетный скрипт, мне нужно удерживать Esc в течение секунды или двух, прежде чем программа выйдет из цикла while, вместо того, чтобы быть мгновенным.

Сначала я подумал, что ввод может быть заблокирован timeout /t 1 /nobreak>nul в пакетном скрипте, но удаление этой строки не имело значения. Я что-то здесь упускаю, что может блокировать ввод?

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Как только ваше консольное приложение запускается adb.exe, оно теряет фокус.Когда приложение не имеет фокуса, оно не получает никакого ввода с клавиатуры, потому что ввод с клавиатуры идет в другое сфокусированное приложение.

Вы можете восстановить фокусировку, выбрав consoleapp с помощью мыши, когда adb.exe работает, а затем нажмите ESC.Но я думаю, это не то, что вам нужно.

Я вижу несколько «решений»:

  • Вы можете найти способ сделать ваше consoleapp всегда приложением верхнего уровня.
  • Сделайте это настольным / Winform-приложением, в котором есть ошибка "QUIT".
1 голос
/ 28 марта 2019

Код ниже должен решить вашу проблему. Обратите внимание, что я переместил тайм-аут из командного файла и поместил его в цикл while.

Program.cs

private static void Main(string[] args)
{
    Console.WriteLine("Press escape to quit");

    do
    {
        while (!Console.KeyAvailable)
        {
            RunBatch();
            Thread.Sleep(1000);
        }
    } while (Console.ReadKey(true).Key != ConsoleKey.Escape);

    Console.WriteLine("While loop has exited");
    Console.ReadLine();
}

private static void RunBatch()
{
    var process = new Process
    {
        StartInfo =
        {
            UseShellExecute = false,
            RedirectStandardOutput = true,
            FileName = @"C:\Dev\Batch\GetTcpConnections.bat"
        }
    };

    process.Start();
    Console.WriteLine(process.StandardOutput.ReadToEnd());
}

GetTcpConnections.bat

@echo off
echo %time%
adb.exe shell cat /proc/net/tcp
...