82 votes

comment exécuter un winform depuis une application console ?

Comment créer, exécuter et contrôler un winform à partir d'une application console ?

108voto

Marc Gravell Points 482669

L'option la plus simple est de démarrer un projet Windows forms, puis de changer le type de sortie en Application Console. Vous pouvez également ajouter une référence à System.Windows.Forms.dll et commencer à coder :

using System.Windows.Forms;

[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.Run(new Form()); // or whatever
}

L'élément important est le [STAThread] sur votre Main() nécessaire pour une prise en charge complète de COM.

8 votes

@Kenny selon msdn, il l'a toujours été.

1 votes

J'utilise vsCode (pas visual studio), j'ai donc dû ajouter à mon fichier csproj le xml suivant : <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> <UseWPF>true</UseWPF> <UseWindowsForms>true</UseWindowsForms> </PropertyGroup> </Project> remarquer le Microsoft.NET.Sdk.WindowsDesktop et le UseWPF>true</UseWPF> et le UseWindowsForms>true</UseWindowsForms>.

42voto

Tergiver Points 8636

J'ai récemment voulu faire cela et j'ai constaté que je n'étais satisfait d'aucune des réponses données ici.

Si vous suivez les conseils de Marc et définissez le type de sortie sur Console Application, il y a deux problèmes :

1) Si vous lancez l'application à partir de l'Explorer, vous obtenez une fenêtre de console gênante derrière votre formulaire qui ne disparaît pas jusqu'à ce que votre programme se termine. Nous pouvons atténuer ce problème en appelant FreeConsole avant de montrer l'interface graphique (Application.Run). Le problème ici est que la fenêtre de la console apparaît toujours. Elle disparaît immédiatement, mais reste tout de même présente pendant un moment.

2) Si vous le lancez depuis une console et que vous affichez une interface graphique, la console est bloquée jusqu'à ce que l'interface graphique sorte. Ceci est dû au fait que la console (cmd.exe) pense qu'elle doit lancer les applications Console de manière synchrone et les applications Windows de manière asynchrone (l'équivalent unix de "myprocess &").

Si vous laissez le type de sortie comme Application Windows, mais correctement appelle AttachConsole, vous n'obtenez pas une deuxième fenêtre de console lorsqu'elle est invoquée à partir d'une console et vous n'obtenez pas la console inutile lorsqu'elle est invoquée à partir de l'explorateur. La façon correcte d'appeler AttachConsole est de lui passer -1. Ainsi, notre processus s'attache à la console de notre processus parent (la fenêtre de console qui nous a lancé).

Cependant, cela pose deux problèmes différents :

1) Comme la console lance les applications Windows en arrière-plan, elle affiche immédiatement l'invite et permet de poursuivre la saisie. D'un côté, c'est une bonne nouvelle, la console n'est pas bloquée sur votre application GUI, mais dans le cas où vous voulez envoyer la sortie vers la console et ne jamais montrer l'interface graphique, la sortie de votre programme vient après l'invite et aucune nouvelle invite n'est affichée lorsque vous avez terminé. Cela semble un peu confus, sans compter que votre "application console" s'exécute en arrière-plan et que l'utilisateur est libre d'exécuter d'autres commandes pendant son exécution.

2) La redirection du flux est également perturbée, par exemple, "myapp some parameters > somefile" ne redirige pas. Le problème de la redirection de flux nécessite une quantité significative de p/Invoke pour réparer les handles standards, mais il est soluble.

Après de nombreuses heures de recherche et d'expérimentation, j'en suis arrivé à la conclusion qu'il n'existe aucun moyen de faire cela parfaitement. Vous ne pouvez tout simplement pas obtenir tous les avantages de la console et de la fenêtre sans aucun effet secondaire. Il s'agit de choisir les effets secondaires les moins gênants pour votre application.

0 votes

J'ajouterais également que pour obtenir la sortie du terminal dans mono de GNU/Linux, une application de fenêtre habituelle est suffisante. C'est à dire Console.WriteLine fonctionne toujours par défaut.

27voto

Voici la meilleure méthode que j'ai trouvée : Tout d'abord, définissez le type de sortie de vos projets sur "Application Windows", puis P/Invoke AllocConsole pour créer une fenêtre console.

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

static class Program
{

    static void Main(string[] args) {
        if (args.Length == 0) {
            // run as windows app
            Application.EnableVisualStyles();
            Application.Run(new Form1()); 
        } else {
            // run as console app
            NativeMethods.AllocConsole();
            Console.WriteLine("Hello World");
            Console.ReadLine();
        }
    }

}

6voto

ZapStorm Points 314

C'est très simple à faire :

Il suffit d'ajouter l'attribut et le code suivants à votre méthode principale :

[STAThread]
void Main(string[] args])
{
   Application.EnableVisualStyles();
   //Do some stuff...
   while(!Exit)
   {
       Application.DoEvents(); //Now if you call "form.Show()" your form won´t be frozen
       //Do your stuff
   }
}

Maintenant vous êtes pleinement capable de montrer WinForms :)

1 votes

Cela fonctionne bien ! Si vous avez besoin de vérifier les frappes, vous devrez vérifier la disponibilité des touches en utilisant Console.KeyAvailable avant d'appeler Console.ReadKey, sinon vous bloquerez la boucle d'événement (et donc vos formulaires).

5voto

David Arno Points 15499

Vous pouvez créer un projet winform dans VS2005/ VS2008, puis modifier ses propriétés pour en faire une application en ligne de commande. Il peut alors être lancé à partir de la ligne de commande, mais il ouvrira toujours une fenêtre winform.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X