Here's the C# code snippet from the console application that works on my local Windows 8, and VS .NET 2015 environment. It also works when I run the console application in an Administrator DOS/CMD window on my local Windows 8 machine.
The Console application (DOS/CMD window opened as Administrator) does not accept the ESC key when using Windows Remote Desktop to connect to a Windows 2012 R2 server.
do
{
while (!Console.KeyAvailable)
{
// Do nothing while waiting for input
}
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
I know Windows 2012 R2 has special keys for special commands when using Remote Desktop, however, this is the ESC key not working with Remote Desktop to Windows 2012 R2 in a DOS/CMD window.
I know I can use a different key (or other combinations), but I want to know why the ESC key is not "accepted" by the DOS/Console window in this scenario.
[EDIT]: Ok, I need to be more specific here.
I'm really trying to run a EXE as a Console Application. The code I posted worked in Windows 2008, but wait there's more! Prior to outputting my results to the CMD/DOS prompt, I must first attach to the existing Parent CMD window. I'm using the code found at the following URL to either a new AllocConsole(), or AttachConsole(). http://www.jankowskimichal.pl/en/2011/12/wpf-hybrid-application-with-parameters/
On both Windows Server 2008, and Windows Server 2012, it writes everything I coded with Console.Write.... at all times.
However, in Windows Server 2012, this code no longer take my input using ReadKey(), or the code posted originally above.
Code Snippet (bool "show" = true does the attach to the console; false detaches). Again, works to output in all cases, but is not taking my input at a Console.ReadKey().
//Declarations area
[DllImport("kernel32.dll",
EntryPoint = "AllocConsole",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern bool AllocConsole();
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeConsole();
[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);
private enum ConsoleCtrlEvent
{
CTRL_C = 0,
CTRL_BREAK = 1,
CTRL_CLOSE = 2,
CTRL_LOGOFF = 5,
CTRL_SHUTDOWN = 6
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GenerateConsoleCtrlEvent(ConsoleCtrlEvent sigevent, int dwProcessGroupId);
[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
private static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
[SNIP]
//Caller:
//Attach or create a console window to display information to the user
DoConsoleWindow(true);
//Determine if user has administrator privileges
if (UserHasAdminPrivileges(args))
{
//Write information to the console
HandleCommandArgs(args);
}
DoConsoleWindow(false);
[SNIP]
private static void DoConsoleWindow(bool show)
{
if (show == true)
{
ptr = GetForegroundWindow();
int u;
GetWindowThreadProcessId(ptr, out u);
process = Process.GetProcessById(u);
if (process.ProcessName == "cmd") //Is the uppermost window a cmd process?
{
AttachConsole(process.Id);
attachedExisting = true;
}
else
{
//no console AND we're in console mode ... create a new console.
AllocConsole();
}
}
else
{
try
{
//Must pause for 2 seconds to allow display of data to catch up?
Thread.Sleep(2000);
//Send the {ENTER} Key to the console.
PostMessage(ptr, WM_KEYDOWN, VK_RETURN, 0);
FreeConsole();
if (process != null)
{
if (attachedExisting != true)
{
process.Close();
}
}
}
catch (Exception ex)
{
Logger.Log(TraceEventType.Error,
string.Format("{0} failed handling console close", serviceName),
string.Format("{0} failed handling console close: {1}",
serviceName, ex.ToString()),
serviceLogContext);
}
}
}
Let's look at your code
The part
is a hot loop. One CPU core will run near 100% polling KeyAvailable. On my 8-core machine the code is still responsive and terminates when ConsoleKey.Escape is pressed. However, it is needlessly inefficient, and if you only have one or limited CPU cores, that may cause the key press event to be missed.
Rewrite to the more efficient
and see if the problem goes away.
I ran both your original code and mine on a Windows 2012 R2 server accessed via Remote Desktop. Both variants worked. I do have several CPU cores available on that server, and one of them did go to 100% with your code.