web-dev-qa-db-fra.com

comment exécuter un winform à partir d'une application console?

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

61
reshefm

L'option la plus simple consiste à démarrer un projet Windows Forms, puis à changer le type de sortie en Application console. Sinon, ajoutez simplement une référence à System.Windows.Forms.dll et démarrez le codage:

using System.Windows.Forms;

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

Le bit important est le [STAThread] de votre méthode Main(), requis pour la prise en charge complète de COM.

87
Marc Gravell

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

Si vous suivez les conseils de Marc et définissez le type de sortie sur Application console, vous rencontrez deux problèmes:

1) Si vous lancez l’application à partir de l’explorateur, une fenêtre de console gênante apparaît derrière votre formulaire et ne disparaît pas tant que votre programme n’a pas été fermé. Nous pouvons atténuer ce problème en appelant FreeConsole avant d'afficher l'interface graphique (Application.Run). Le problème, c'est que la fenêtre de la console apparaît toujours. Il s'en va aussitôt, mais est là pour un moment quand même.

2) Si vous le lancez à partir d'une console et affichez une interface graphique, la console est bloquée jusqu'à ce que l'interface graphique se ferme. En effet, la console (cmd.exe) pense qu'elle devrait lancer les applications de console de manière synchrone et les applications de Windows de manière asynchrone (l'équivalent unix de "myprocess &").


Si vous laissez le type de sortie en tant qu'application Windows, mais que correctement appelle AttachConsole, vous n'obtiendrez pas de seconde fenêtre de console lorsqu'il est appelé à partir d'une console et vous n'obtenez pas la console inutile lorsqu'il est appelé à partir de l'Explorateur. . La bonne façon d'appeler AttachConsole est de lui passer -1. Cela force notre processus à s’attacher à la console de notre processus parent (la fenêtre de la console qui nous a lancé).

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

1) Etant donné que la console lance les applications Windows en arrière-plan, elle affiche immédiatement l'invite et autorise d'autres entrées. D’une part, c’est une bonne nouvelle: la console n’est pas bloquée sur votre application GUI, mais dans le cas où vous souhaitez vider la sortie sur la console et ne jamais afficher la GUI, la sortie de votre programme arrive après l’invite et aucune nouvelle invite n’est affichée. affiché lorsque vous avez terminé. Cela semble un peu déroutant, sans compter que votre "application console" est exécutée en arrière-plan et que l'utilisateur est libre d'exécuter d'autres commandes pendant son exécution.

2) La redirection de flux est également perturbée, par ex. "mon application certains paramètres> un fichier" ne parvient pas à rediriger. Le problème de la redirection de flux nécessite une quantité importante de p/Invoke pour corriger les descripteurs standard, mais il peut être résolu .


Après de nombreuses heures de chasse et d’expérimentation, je suis parvenu à la conclusion qu’il n’était pas possible de le faire parfaitement. Vous ne pouvez tout simplement pas obtenir tous les avantages de la console et de la fenêtre sans aucun effet secondaire. C'est une question de choisir les effets secondaires les moins gênants pour les besoins de votre application.

32
Tergiver

Voici la meilleure méthode que j'ai trouvée:.

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();
        }
    }

}
23

C'est très simple à faire:

Ajoutez simplement l'attribut et le code suivants à votre méthode Main:

[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
   }
}

Vous êtes maintenant tout à fait capable de montrer WinForms :)

6
SharpShade

Vous pouvez créer un projet Winform dans VS2005/VS2008, puis modifier ses propriétés pour qu’il s’agisse d’une application en ligne de commande. Il peut ensuite être démarré à partir de la ligne de commande, mais ouvrira quand même un winform.

4
David Arno

Vous devriez pouvoir utiliser la classe Application de la même manière que les applications Winform. Le moyen le plus simple de démarrer un nouveau projet est probablement de faire ce que Marc a suggéré: créer un nouveau projet Winform, puis le modifier dans les options en une application console.

0
Grzenio

Cela a fonctionné pour mes besoins ...

Task mytask = Task.Run(() =>
{
    MyForm form = new MyForm();
    form.ShowDialog();
});

Cela démarre le dans un nouveau thread et ne le libère pas tant que le formulaire n'est pas fermé. Task est dans .Net 4 et versions ultérieures. 

0
Sunsetquest

Si vous voulez échapper à Gel de formulaire et utiliser l'édition (comme du texte pour un bouton) utiliser ce code

Form form = new Form();
Form.Button.Text = "randomText";
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.Run(form);
0

Toutes les réponses ci-dessus sont d'une grande aide, mais j'ai pensé ajouter quelques astuces supplémentaires au débutant absolu.

Donc, vous voulez faire quelque chose avec Windows Forms, dans une application console:

Ajoutez une référence à System.Windows.Forms.dll dans votre projet d'application console dans l'Explorateur de solutions. (Clic droit sur Nom de la solution-> ajouter-> Référence ...)

Spécifiez l'espace de nom dans le code: using System.Windows.Forms;

Déclarez les propriétés nécessaires dans votre classe pour les contrôles que vous souhaitez ajouter au formulaire.

par exemple. int Left { get; set; } // need to specify the LEFT position of the button on the Form

Et ajoutez ensuite l'extrait de code suivant dans Main():

static void Main(string[] args)
{
Application.EnableVisualStyles();
        Form frm = new Form();  // create aForm object

        Button btn = new Button()
        {
            Left = 120,
            Width = 130,
            Height = 30,
            Top = 150,
            Text = "Biju Joseph, Redmond, WA"
        };
       //… more code 
       frm.Controls.Add(btn);  // add button to the Form
       //  …. add more code here as needed

       frm.ShowDialog(); // a modal dialog 
}
0
Biju Joseph

Cela dépend totalement de votre choix, de la manière dont vous l'implémentez.
une. Processus attaché, ex: saisie sur formulaire et impression sur console 
b. Processus indépendant, ex: démarrer une minuterie, ne ferme pas même si la console est sortie.

pour un,

Application.Run(new Form1());
//or -------------
Form1 f = new Form1();
f.ShowDialog();

pour b, Utilisez un fil, ou une tâche quelconque, Comment ouvrir un formulaire gagnant indépendamment?

0
Raj kumar