2008-11-10 7 views

Répondre

76

L'option la plus simple consiste à démarrer un projet Windows Forms, puis à modifier le type de sortie à Application console. Sinon, il suffit d'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 
} 

Le bit important est le [STAThread] sur votre méthode Main(), nécessaire pour un support complet COM.

+4

Le STAThread était en effet la chose qui fait la différence ... – reshefm

+0

'STAThreadAttribute' est dans la Espace de noms 'System' dans .NET 4. –

+6

@Kenny selon msdn il a toujours été –

4

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

0

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

19

Voici la meilleure méthode que j'ai trouvée: , définissez le type de sortie de vos projets sur "Application Windows", puis sur P/Invoke AllocConsole pour créer une fenêtre de 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(); 
     } 
    } 

} 
+2

-1, crée une deuxième fenêtre de console et exécute la commande là. Pas ce que l'OP voulait. – tomfanning

+7

en fait cela ne crée pas une seconde console, parce que vous définissez la sortie du projet sur Windows Application en premier, ce qui n'est pas ce que l'OP a demandé, mais probablement ce qu'il voulait, parce que vous n'avez pas la console fenêtre lorsque vous n'en avez pas besoin – DrCopyPaste

+0

fonctionne comme annoncé, bien que je ne reçois pas l'icône de l'application et je ne pense pas que le "répertoire de travail actuel" est le même - des idées? – drzaus

6

Il est très simple à faire:

ajouter simplement attribut et code suivant à 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 en mesure de montrer WinForms :)

+1

Fonctionne bien! Si vous devez vérifier les frappes, vous devrez vérifier la disponibilité des clés en utilisant Console.KeyAvailable avant d'appeler Console.ReadKey, sinon vous allez bloquer la boucle d'événement (et donc vos formulaires) – wexman

+0

Merci pour l'ajout @wexman I oublié à ce sujet. – SharpShade

26

J'ai récemment voulu faire ceci et ai trouvé que je n'étais pas heureux avec aucune des réponses ici.

Si vous suivez les conseils de Marc et de définir le type de sortie à l'application de la console, il y a deux problèmes:

1) Si vous lancez l'application à partir d'Explorer, vous obtenez une fenêtre de console ennuyeux derrière votre formulaire qui ne partez jusqu'à ce que votre programme se termine. Nous pouvons atténuer ce problème en appelant FreeConsole avant d'afficher l'interface graphique (Application.Run). L'ennui ici est que la fenêtre de la console apparaît toujours. Il s'en va immédiatement, mais il est là pour un moment.

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 termine. En effet, 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 appel AttachConsole, vous ne recevez pas une seconde fenêtre de la console lorsqu'elle est appelée à partir d'une console et vous ne recevez pas la console inutile lorsque invoqué depuis Explorer. La façon correcte d'appeler AttachConsole est de lui passer -1. Cela provoque notre processus à attacher à la console de notre processus parent (la fenêtre de la console qui nous a lancé).

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

1) Parce que la console lance applications Windows en arrière-plan, il affiche immédiatement l'invite et permet une entrée plus loin.D'une part c'est une bonne nouvelle, la console n'est pas bloquée sur votre application graphique, mais dans le cas où vous voulez exporter la sortie vers la console et ne jamais afficher l'interface graphique, la sortie de votre programme vient après l'invite et aucune nouvelle invite affiché lorsque vous avez terminé. Cela semble un peu confus, pour ne pas mentionner que votre «console app» est en cours d'exécution en arrière-plan et 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. "myapp certains paramètres> certains fichiers" ne parvient pas à rediriger. Le problème de redirection de flux nécessite une quantité significative de p/Invoke pour corriger les poignées standard, mais il est résoluble.


Après de nombreuses heures de chasse et d'expérimentation, je suis venu à la conclusion qu'il n'y a aucun moyen de le faire parfaitement. Vous ne pouvez tout simplement pas obtenir tous les avantages de la console et de la fenêtre sans effets secondaires. Il s'agit de choisir quels effets secondaires sont les moins gênants pour les besoins de votre application.

+0

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

0

Cela a fonctionné pour mes besoins ...

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

Cela commence le à partir dans un nouveau thread et ne libère pas le fil jusqu'à ce que la forme est fermée. Task est dans .Net 4 et versions ultérieures.

0

Cela dépend totalement de votre choix, de la façon dont vous le mettez en œuvre.
a. Processus attaché, ex: entrée sur formulaire et impression sur console
b. Processus indépendant, ex: démarrer une minuterie, ne pas fermer même si la sortie de la console.

pour un,

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

pour b, fil d'utilisation, ou quoi que ce soit la tâche, How to open win form independently?

Questions connexes