Il seguente programma genera un errore su "Console.ReadKey()".Come chiudere/aprire la console in C# usando le chiamate Win32?
Come posso riattivare la console dopo disabilitarlo?
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem((o) =>
{
Thread.Sleep(1000);
IntPtr stdin = GetStdHandle(StdHandle.Stdin);
CloseHandle(stdin);
});
Console.ReadLine();
Console.Write("ReadLine() successfully aborted by background thread.\n");
Console.Write("[any key to exit]");
Console.ReadKey(); // Throws an exception "Cannot read keys when either application does not have a console or when console input has been redirected from a file. Try Console.Read."
}
// P/Invoke:
private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 };
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(StdHandle std);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hdl);
}
}
Extra per Esperti
Se vi state chiedendo, ho bisogno di essere in grado di uccidere un thread in background in esecuzione ReadLine(), all'interno di C#. Questo sembra essere l'unico modo (thread.Abort non funzionerà perché ReadLine() viene eseguito in profondità nelle viscere del sistema operativo, nel codice non gestito). Ci sono molte discussioni su questo argomento su StackOverflow, nessuno ha mai scoperto (o pubblicato) un metodo soddisfacente per interrompere Console.ReadLine(). Penso che questo codice sia sulla strada giusta, se solo potessimo riabilitare la console dopo averla disabilitata.
Se chiudi la maniglia ... Dovresti aprirla manualmente. Considerando che hai appena chiuso il Gestore non c'è garanzia, puoi usare di nuovo lo stesso Handle. Sei sicuro di aver chiuso la maniglia corretta? Devo credere che ci sia un modo più semplice per abortire una Readline e poi chiudere la maniglia insanguinata dello standard input. –
@Ramhound Mi piacerebbe che esistesse un modo più semplice per abortire ReadLine. Ho provato tutto - .Abort, invio chiavi all'applicazione (che funziona solo per il focus corrente), ecc. Se c'è un modo migliore, sono tutto orecchie. – Contango
@Ramhound L'unico altro modo in cui posso pensare è scrivere un clone di ReadLine in C# gestito al 100%, quindi .Abort funzionerà, che è certamente più complesso rispetto a poche righe di codice Win32. – Contango