Reputation: 5163
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
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":
Upvotes: 2
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