Remy
Remy

Reputation: 5163

Console app only terminates when holding key down while running batch script

I am trying to create a C# console application that repeatedly runs a .bat file and saves the output into a variable to be modified later. The script is meant to get open TCP connections on a connected device using adb.exe.

I want the application to quit when the Esc key is pressed (once). To accomplish this I followed this answer and implemented it like so:

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

The expected result would be, that the console application exits the loop and prints While loop was exited directly upon pressing Esc. It works like this when I comment RunBatch() and un-comment Console.WriteLine("Application is running". However, when I am running the batch script, I need to hold down Esc for about a second or two before the program exits the while loop, instead of being instantaneous.

At first I thought that the input may be blocked by timeout /t 1 /nobreak>nul in the batch script, but removing this line made no difference. Am I missing something else here that could block inputs?

Upvotes: 2

Views: 176

Answers (2)

Martin Mulder
Martin Mulder

Reputation: 12954

As soon as your consoleapp starts adb.exe, it looses the focus. When an applicaties does not have the focus, it does not receive any keyboard input, because the keyboard input goes to another focused application.

You can reclaim the focus by selecting the consoleapp with your mouse, while adb.exe is running, and than press ESC. But I guess that is not what you want.

I see serveral "solutions":

  • You could find a way to make your consoleapp always the top-level applicatie.
  • Make it a Desktop / Winform-application which has a bug "QUIT"-button.

Upvotes: 2

prd
prd

Reputation: 2311

The code below should solve your problem. Note that I have moved the timeout away from the batch file and placed it within the while loop.

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

Upvotes: 1

Related Questions