49 votes

Comment créer une application C# qui décide elle-même de s'afficher en tant qu'application console ou fenêtre ?

Existe-t-il un moyen de lancer une application C# avec les caractéristiques suivantes ?

  1. Il détermine par les paramètres de la ligne de commande s'il s'agit d'une application fenêtrée ou console.
  2. Il n'affiche pas de console lorsqu'on lui demande d'être fenêtré et n'affiche pas de fenêtre GUI lorsqu'il est exécuté depuis la console.

Par exemple,

myapp.exe /helps'affiche dans la sortie stdout de la console que vous utilisez, mais    myapp.exelancerait à elle seule mon interface utilisateur Winforms ou WPF.  

Les meilleures réponses que je connaisse jusqu'à présent impliquent d'avoir deux exe séparés et d'utiliser l'IPC, mais cela semble très compliqué.

Quelles sont les options dont je dispose et les compromis que je peux faire pour obtenir le comportement décrit dans l'exemple ci-dessus ? Je suis ouvert aux idées qui sont spécifiques à Winform ou WPF, aussi.

58voto

Eric Petroelje Points 40734

Faites de l'application une application Windows ordinaire, et créez une console à la volée si nécessaire.

Plus de détails à l'adresse suivante ce lien (code ci-dessous à partir de là)

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
        if ( !AttachConsole(-1) ) { // Attach to an parent process console
           AllocConsole(); // Alloc a new console
        }

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

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern bool AttachConsole(int pid);

  }
}

17voto

adabyron Points 4335

Je procède essentiellement de la manière décrite dans la réponse d'Eric, en plus je détache la console avec FreeConsole et utilise la commande SendKeys pour récupérer l'invite de commande.

    [DllImport("kernel32.dll")]
    private static extern bool AllocConsole();

    [DllImport("kernel32.dll")]
    private static extern bool AttachConsole(int pid);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool FreeConsole();

    [STAThread]
    static void Main(string[] args)
    {
        if (args.Length > 0 && (args[0].Equals("/?") || args[0].Equals("/help", StringComparison.OrdinalIgnoreCase)))
        {
            // get console output
            if (!AttachConsole(-1))
                AllocConsole();

            ShowHelp(); // show help output with Console.WriteLine
            FreeConsole(); // detach console

            // get command prompt back
            System.Windows.Forms.SendKeys.SendWait("{ENTER}"); 

            return;
        }

        // normal winforms code
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());

    }

7voto

TheTXI Points 24470

Écrire deux applications (une console, une Windows), puis écrire une autre application plus petite qui, en fonction des paramètres donnés, ouvre l'une des autres applications (puis se fermerait probablement elle-même puisqu'elle ne serait plus nécessaire) ?

5voto

Anthony Brien Points 2069

Pour ce faire, j'ai créé deux applications distinctes.

Créez l'application WPF avec ce nom : MyApp.exe . Et créez l'application console avec ce nom : MyApp.com . Lorsque vous tapez le nom de votre application dans la ligne de commande comme ceci MyApp ou MyApp /help (sans .exe ) l'application console avec l'extension .com aura la priorité. Vous pouvez demander à votre application console d'invoquer le MyApp.exe en fonction des paramètres.

C'est exactement le comportement de devenv. Taper devenv à la ligne de commande lancera l'IDE de Visual Studio. Si vous passez des paramètres comme /build il restera dans la ligne de commande.

4voto

Reed Copsey Points 315315

NOTE : Je n'ai pas testé ceci, mais je crois que cela fonctionnerait...

Tu pourrais faire ça :

Faites de votre application une application Windows forms. Si vous recevez une demande de console, n'affichez pas votre formulaire principal. Au lieu de cela, utilisez platform invoke pour faire appel à l'application Fonctions de la console dans l'API Windows et allouer une console à la volée.

(Vous pouvez également utiliser l'API pour masquer la console dans une application console, mais vous verriez probablement la console "vaciller" lors de sa création dans ce cas...)

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