2010-05-11 4 views
12

Je souhaite que l'une de mes applications Windows Forms soit exécutée par programme, à partir de la ligne de commande. En préparation, j'ai séparé la logique de sa propre classe de la forme. Maintenant, je suis bloqué en essayant de faire basculer l'application en fonction de la présence d'arguments de ligne de commande.Application .NET s'exécutant en tant que Windows Form ou en tant qu'application de console

Voici le code pour la classe principale:

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     string[] args = Environment.GetCommandLineArgs(); 
     if (args.Length > 1) // gets passed its path, by default 
     { 
      CommandLineWork(args); 
      return; 
     }   

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 

    private static void CommandLineWork(string[] args) 
    { 
     Console.WriteLine("It works!"); 
     Console.ReadLine(); 
    } 

Form1 est ma forme et la chaîne It works! est juste un espace réservé pour la logique réelle.

À l'heure actuelle, lors de l'exécution à partir de Visual Studio (avec des arguments de ligne de commande), la phrase It works! est imprimée sur la sortie. Cependant, lors de l'exécution du fichier /bin/Debug/Program.exe (ou/Release d'ailleurs), l'application se bloque.

Est-ce que je vais dans ce sens? Serait-il plus logique (c'est-à-dire de prendre moins de temps de développement) que ma classe logique soit une DLL chargée par deux applications distinctes? Ou y a-t-il quelque chose de complètement différent que je ne connais pas?

Merci d'avance!

+0

Quelle exception obtenez-vous lorsque l'application tombe en panne? Aussi, je suppose qu'il devrait être args.Length> = 1 (ou> 0) au lieu de> 1? –

Répondre

22

Vous aurez besoin de P/Invoke AllocConsole() si vous détectez un argument de ligne de commande. Vérifiez ma réponse en this thread pour le code requis. Un échantillon C# est plus bas sur la page. Répétais ici parce que je ne fais pas confiance ce site forum crummy:

using System; 
using System.Windows.Forms; 

namespace WindowsApplication1 { 
    static class Program { 
    [STAThread] 
    static void Main(string[] args) { 
     if (args.Length > 0) { 
     // Command line given, display console 
     AllocConsole(); 
     ConsoleMain(args); 
     } 
     else { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
     } 
    } 
    private static void ConsoleMain(string[] args) { 
     Console.WriteLine("Command line = {0}", Environment.CommandLine); 
     for (int ix = 0; ix < args.Length; ++ix) 
     Console.WriteLine("Argument{0} = {1}", ix + 1, args[ix]); 
     Console.ReadLine(); 
    } 

    [System.Runtime.InteropServices.DllImport("kernel32.dll")] 
    private static extern bool AllocConsole(); 
    } 
} 
+1

Vous pouvez également utiliser 'FreeConsole': http://stackoverflow.com/questions/1786840/c-is-it-possible-to-have-a-single-application-behave-as-console-or-windows-appl/1787008 # 1787008 – adrianbanks

+1

Pourquoi ne pas en faire une application de console en premier lieu, puis faire référence à l'assemblage de formulaires pour le fenêtrage? –

+0

@Chris: obtenir une console uniquement à la demande, pas toujours. FreeConsole est un flash * méchant. –

1

Oui, il serait préférable de faire deux .exes frontend (un pour la ligne de commande et un pour la fenêtre).

La raison principale est que vous devez spécifier le type de sortie pour votre projet (soit la ligne de commande ou de l'application Windows et que vous ne pouvez pas sélectionner les deux.

donc vous devez toujours utiliser le type de sortie d'application Windows (qui vient à une surcharge pour le système de messagerie Windows et ne vous donne pas la ligne de commande « réel »).

1

Je ne sais pas si cela fait une différence, mais au lieu de

static void Main() 
{ 
     string[] args = Environment.GetCommandLineArgs(); 

vous pouvez mettre à la place

static void Main(string[] args) 
{ 
+2

Comme ce n'est pas une solution au problème, cela devrait être un commentaire pas une réponse? – Peter

0

Est-ce que vous allez réellement fonctionner comme une application réelle de la console à demander à l'utilisateur d'entrer des données, etc., ou êtes-vous simplement allez commencer vers le haut avec quelques arguments afin qu'il puisse être exécuté à partir d'un fichier batch ou d'une tâche planifiée ou similaire?

Si c'est une application de console réelle, je serais d'accord avec Foxfire que ça vaut probablement la peine d'avoir 2 fichiers exe, mais sinon je le garderais comme un exe. J'ai fait beaucoup de ceux sans problèmes.

Quelle est l'exception exacte qui se produit cependant?

0

Accédez aux propriétés du projet

Dans l'onglet Application vous devriez voir une liste déroulante nommée Type de sortie. Changez pour Console Application.

Là, vous avez à la fois une fenêtre et une console. Maintenant, votre code avec l'argument de commande devrait fonctionner.

Questions connexes