web-dev-qa-db-fra.com

Comment obtenir le handle de la fenêtre d'une application console

Quelqu'un peut-il me dire comment obtenir le handle d'une application console Windows en C #? Dans une application Windows Forms, j'essayerais normalement this.Handle.

37
Grant

Pas sûr que ça marche, mais vous pouvez essayer ça:

IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
55
Thomas Levesque

Essaye ça:

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName);
…

Console.Title = "Test";
…

IntPtr handle = FindWindowByCaption(IntPtr.Zero, Console.Title);
10
Zain Ali

Je viens de résoudre ce problème pour moi-même (malheureusement avant de voir réponse de Thomas qui est beaucoup plus rapide). Eh bien, voici une autre façon pour ceux qui ne sont pas satisfaits de sa réponse. J'écris cette réponse car je souhaite fournir une autre réponse + un meilleur moyen de concevoir la classe Program si vous traitez votre console comme une fenêtre. Commençons par cette conception:

J'ai en quelque sorte changé le style par défaut de la classe Program. En fait, j'en ai fait une classe qui contient un programme et non une méthode qui le représente et qui utilise d'autres classes pour le contenu. (Si vous ne savez pas ce que je veux dire, pas important).

La raison pour laquelle je devais le faire est que je voulais écrire le gestionnaire d'événements suivant:

private void CatchUnhandled(Object sender, UnhandledExceptionEventArgs e)
{
    var exception = e.ExceptionObject as Exception;
    MessageBox.Show(this, exception.Message, "Error"); // Check out 1st arg.
}

Il surcharge cette méthode MessageBox.Show(IWin32Window, String, String) .

Comme la console n’implémente pas IWin32Window , j’ai dû l’implémenter moi-même, bien sûr, pour pouvoir appeler this dans le 1st argument.

Voici son implémentation et tout le reste:

_ {Remarque: ce code est copié-collé depuis mon application, vous pouvez changer les modificateurs d'accès} _

Program Déclaration de classe:

internal class Program : IWin32Window
{
    ...
}

IWin32Window Implémentation:

public IntPtr Handle
{
    get { return NativeMethods.GetConsoleWindow(); }
}

Il utilise la classe suivante:

internal static class NativeMethods
{
    [DllImport("kernel32.dll")]
    internal static extern IntPtr GetConsoleWindow();
}

Le problème est que vous ne pouvez pas appeler this dans Main, en tant que méthode statique. Ainsi, tout ce qui était dans Main est passé à une nouvelle méthode nommée Start et que tout Main fait crée un nouveau Program et appelle Start.

private static void Main()
{
    new Program().Start();
}

private void Start()
{
    AppDomain.CurrentDomain.UnhandledException += CatchUnhandled;

    throw new Exception();
}

Le résultat fut, bien sûr, une boîte de message avec la fenêtre de ma console en tant que propriétaire. 
L'utilisation de cette méthode pour une boîte de message ne constitue bien entendu qu'une application de cette méthode.

7
MasterMastic

Je ne pense pas qu'il existe une telle chose. La fenêtre de la console n'est pas accessible à l'application. Vous POUVEZ essayer de parcourir la liste des processus à la recherche de votre propre nom de processus. La classe Process IIRC contient une propriété pour le handle de la fenêtre principale du programme, qui pourrait est la fenêtre de la console pour les applications console - dont je ne suis pas sûr.

1
Thorsten Dittmar

Dans une application console qui transmettait des diagostiques à la console et pour laquelle je voulais désactiver l'entrée de la souris, j'ai essayé GetConsoleWindow(), Process.GetCurrentProcess().MainWindowHandle, and FindWindowByCaption(IntPtr.Zero, Console.Title). Chacun de ces outils renvoyait le même descripteur différent de zéro, mais lorsque j'ai essayé d'utiliser ce descripteur dans SetConsoleMode, une exception "Invalid Handle" a été lancée. Enfin, j'ai essayé SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode | ENABLE_EXTENDED_FLAGS)) avec STD_INPUT_HANDLE défini sur -10, et cela a fonctionné. La documentation de MS suggère que les poignées des consoles peuvent être réaffectées et je ne suis pas à l'aise avec cette solution, mais jusqu'à présent, c'est la seule chose que j'ai trouvée qui me permette de désactiver le mode d'édition rapide par programmation. GetStdHandle(STD_INPUT_HANDLE) renvoie '3', les autres appels renvoient une valeur à 7 chiffres qui varie chaque fois que le programme est exécuté.

0
mickeyf