Comment exécuter une application console C # avec la console masquée

141

Existe-t-il un moyen de masquer la fenêtre de la console lors de l'exécution d'une application de console?

J'utilise actuellement une application Windows Forms pour démarrer un processus de console, mais je ne souhaite pas que la fenêtre de la console s'affiche pendant l'exécution de la tâche.

Aaron Thomas
la source
essayez d'exécuter l'application console à partir d'une tâche planifiée.

Réponses:

158

Si vous utilisez la ProcessStartInfoclasse, vous pouvez définir le style de fenêtre sur hidden - dans le cas des applications console (et non GUI), vous devez définir CreateNoWindow sur true:

System.Diagnostics.ProcessStartInfo start =
      new System.Diagnostics.ProcessStartInfo();
start.FileName = dir + @"\Myprocesstostart.exe";
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; //Hides GUI
start.CreateNoWindow = true; //Hides console
Adam Markowitz
la source
26
Juste ce que j'allais publier :)
Jon Skeet
75
Putain de merde - quelqu'un de plus rapide que Jon! =)
Erik Forbes
75
J'ai dû étrangler sa connexion Internet pour le battre;)
Adam Markowitz
11
Cela ne fonctionnait pas pour appeler un outil de ligne de commande. Utilisé votre processus.StartInfo.CreateNoWindow = true; à la place, voir ci-dessous.
Christian
12
Ne masque pas la fenêtre de la console, StartInfo.CreateNoWindow = true est requis.
Daniel
201

Si vous avez écrit l'application console, vous pouvez la masquer par défaut.

Créez une nouvelle application console puis changez le type "Type de sortie" en "Application Windows" (fait dans les propriétés du projet)

Simon
la source
6
J'essayais de cacher ma propre console, de ne pas appeler autre chose, puis de la cacher (comme le suppose la réponse acceptée) - c'était donc la meilleure pour moi. Merci!
iamserious
6
Merci mon pote ! C'est ce que je cherchais aussi!
Varun Sharma
3
La réponse acceptée suppose cela parce que c'est indiqué dans la question.
aqua
façon la plus simple..vraiment aimé..nous ne voulons certainement pas montrer la fenêtre car elle va lancer un autre processus pour moi ..
Sai Avinash
1
Celui-ci contourne les problèmes avec ProcessStartInfo où vous spécifiez les informations d'identification de l'utilisateur et cet utilisateur se trouve être connecté ou l'utilisateur actuel. Dans cette situation, la propriété CreateNoWindow est ignorée afin que vous obteniez toujours une fenêtre de console. En définissant l'application console sur Windows Application mais sans fenêtre, vous n'obtenez aucune fenêtre.
tjmoore
67

Si vous utilisez Process Class, vous pouvez écrire

yourprocess.StartInfo.UseShellExecute = false;
yourprocess.StartInfo.CreateNoWindow = true;

avant yourprocess.start();et le processus sera caché

Peter Mortensen
la source
4
Bonne chance si vous devez arrêter ce processus tôt. Process.Kill se termine brusquement. Process.CloseMainWindow échoue. GenerateConsoleCtrlEvent ne parvient pas à envoyer ctrl + c ou ctrl + break au processus. WM_CLOSE à toutes les fenêtres de thread du processus échoue. Il semble qu'il n'y ait aucun moyen de terminer proprement un processus démarré avec ces deux valeurs de paramètres. Voir ma question ici: stackoverflow.com/questions/16139571/…
Triynko
Merci beaucoup, c'était le plus simple. De plus, si vous possédez (ou dépt) le code de la console, j'ai trouvé que cet exemple de mutex était le plus simple pour un arrêt propre. stackoverflow.com/a/31586184/1877412
cbuteau
1
@Triynko: Vous ne pouvez pas terminer proprement un processus, à moins que ce processus ne coopère activement. Ce n’est pas une question de drapeaux ou d’autre chose. Il n'y a tout simplement rien dans le système d'exploitation qui puisse déclencher un arrêt propre. La solution courante ici est d'utiliser un objet noyau en attente, qui est signalé dans le processus de contrôle, lorsque le processus esclave doit se terminer. Le processus esclave doit surveiller activement l'état de cet objet en attente et lancer un arrêt propre une fois qu'il est signalé.
IInspectable
43

La réponse simple est la suivante: Accédez aux propriétés de votre application console (propriétés du projet). Dans l'onglet "Application", changez simplement le "Type de sortie" en "Application Windows". C'est tout.

Cihan
la source
4
Bullseye. Cela revient à créer une application Windows qui n'appelle aucun formulaire.
ashes999
1
C'est la bonne réponse. Aucun de vos autres pansements ne s'approche. C'est la bonne réponse. Vous voulez que votre application n'ouvre jamais une console en premier lieu. En outre, vous souhaitez pouvoir ouvrir un formulaire à tout moment. Vous appelez donc simplement le formulaire quand vous le souhaitez. c'est-à-dire que notre formulaire est appelé lorsque l'utilisateur clique avec le bouton droit de la souris sur l'icône de la barre d'état système et sélectionne les préférences. CECI EST LA BONNE RÉPONSE !!!
Bluebaron
20

Vous pouvez utiliser l' API FreeConsole pour détacher la console du processus:

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

(bien sûr cela n'est applicable que si vous avez accès au code source de l'application console)

Thomas Levesque
la source
Je voulais ne pas montrer la console. Bien que FreeConsolefasse ce que son nom dit, cela n'empêche pas Windows d'afficher la console avant qu'elle ne soit appelée.
Jader Dias
5
Ensuite, compilez le projet en tant qu'application Windows, pas en tant qu'application console
Thomas Levesque
1
Pour mémoire, c'est exactement ce dont j'avais besoin, merci. Il est aussi exactement ce que le titre demande :) Donc , dans l'intérêt d'autres Voyagers google, 1
sehe
3
De plus [DllImport("kernel32.dll")] static extern bool AllocConsole();vous permet de facilement exécuter avec une console à partir d' une application standard Win32
sehe
1
Fonctionne pour mon application .NET Core 2.2 - si quelqu'un le recherche spécifiquement.
Médisme du
7

Si vous êtes intéressé par la sortie, vous pouvez utiliser cette fonction:

private static string ExecCommand(string filename, string arguments)
{
    Process process = new Process();
    ProcessStartInfo psi = new ProcessStartInfo(filename);
    psi.Arguments = arguments;
    psi.CreateNoWindow = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.UseShellExecute = false;
    process.StartInfo = psi;

    StringBuilder output = new StringBuilder();
    process.OutputDataReceived += (sender, e) => { output.AppendLine(e.Data); };
    process.ErrorDataReceived += (sender, e) => { output.AppendLine(e.Data); };

    // run the process
    process.Start();

    // start reading output to events
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();

    // wait for process to exit
    process.WaitForExit();

    if (process.ExitCode != 0)
        throw new Exception("Command " + psi.FileName + " returned exit code " + process.ExitCode);

    return output.ToString();
}

Il exécute le programme de ligne de commande donné, attend qu'il se termine et renvoie la sortie sous forme de chaîne.

JCH2k
la source
4

Si vous créez un programme qui ne nécessite pas d'entrée utilisateur, vous pouvez toujours simplement le créer en tant que service. Un service n'affichera aucun type d'interface utilisateur.

Chris Bregg
la source
Mais si tout ce que vous voulez faire est d'exécuter le processus jusqu'à ce qu'il se termine, par exemple en l'appelant depuis le planificateur de tâches, alors un service est gênant car il continue d'exister. Dans certaines situations, il est très pratique de changer le type de sortie en application Windows par rapport à l'autre ProcessWindowStyle comme masqué.
subsci
2

Ajoutez ceci à votre classe pour importer le fichier DLL:

[DllImport("user32.dll")] 
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 

[DllImport("kernel32.dll")] 
static extern IntPtr GetConsoleWindow();

const int SW_HIDE = 0;
const int SW_SHOW = 5;

Et puis si vous souhaitez le masquer, utilisez cette commande:

 var handle = GetConsoleWindow();
 ShowWindow(handle, SW_HIDE);

Et si vous souhaitez afficher la console:

var handle = GetConsoleWindow();
ShowWindow(handle, SW_SHOW);
IDK quoi que ce soit
la source
1
[DllImport ("user32.dll")] booléen externe statique ShowWindow (IntPtr hWnd, int nCmdShow); [DllImport ("kernel32.dll")] statique extern IntPtr GetConsoleWindow (); const int SW_HIDE = 0; const int SW_SHOW = 5;
soulmachine
1

Je sais que je ne réponds pas exactement à ce que vous voulez, mais je me demande si vous posez la bonne question.

Pourquoi n'utilisez-vous pas non plus:

  1. service Windows
  2. créez un nouveau fil et exécutez votre processus dessus

Cela ressemble à de meilleures options si tout ce que vous voulez est d'exécuter un processus.

Nathan Koop
la source
3
Il existe de nombreux scénarios où le lancement d'une application de console utilitaire est parfaitement légitime.
Adam Robinson
Dans mon cas, un processus distinct est nécessaire en raison du modèle client / serveur utilisé par le logiciel sur lequel je travaille.
Aaron Thomas
Cela ne résout pas toujours le problème de créer un nouveau fil. Il y a des moments où vous ne voulez tout simplement pas la fenêtre ennuyeuse en arrière-plan. De plus, que se passe-t-il si vous avez un process.start en boucle, alors vous n'obtiendrez aucun travail, car les fenêtres de la console apparaissent sur votre visage.
user890332
1
Je lance des applications de console utilitaires sans fenêtre à partir du planificateur de tâches. Pas besoin de service, ni de processus parent à partir duquel bifurquer un thread. Ces applications écrivent dans le EventLog si une sortie supplémentaire est nécessaire.
subsci
1

Bien que, comme d'autres réponses ici l'ont indiqué, vous pouvez changer le "Type de sortie" en "Application Windows", sachez que cela signifie que vous ne pouvez pas l'utiliser Console.Incar il deviendra un NullStreamReader.

Console.Outet Console.Errorsemblent toujours bien fonctionner cependant.

kjbartel
la source
2
Es-tu sérieux? Pourquoi quelqu'un utiliserait Console.In-il quand il n'y a pas de console pour entrer quelque chose? D'où doit venir quelque chose qui peut être consulté via Console.In? Cela n'a aucun sens. En d'autres termes: il est tout à fait évident et logique que ce Console.Insoit un NullStreamReaderdans ce cas.
Robert S.
1
@RobertS. Une pipe peut-être. Ie la sortie d'un autre programme. C'était mon cas d'utilisation quand j'ai découvert cela.
kjbartel
1

Basé sur la réponse d'Adam Markowitz ci-dessus, ce qui suit a fonctionné pour moi:

process = new Process();
process.StartInfo = new ProcessStartInfo("cmd.exe", "/k \"" + CmdFilePath + "\"");
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
//process.StartInfo.UseShellExecute = false;
//process.StartInfo.CreateNoWindow = true;
process.Start();
Volcan Baru
la source
1

J'ai une solution générale à partager:

using System;
using System.Runtime.InteropServices;

namespace WhateverNamepaceYouAreUsing
{
    class Magician
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        const int HIDE = 0;
        const int SHOW = 5;

        public static void DisappearConsole()
        {
            ShowWindow(GetConsoleWindow(), HIDE);
        }
    }
}

Incluez simplement cette classe dans votre projet et appelez Magician.DisappearConsole(); .

Une console clignotera lorsque vous démarrez le programme en cliquant dessus. Lors de l'exécution à partir de l'invite de commande, l'invite de commande disparaît très peu de temps après l'exécution.

Je fais cela pour un Discord Bot qui s'exécute pour toujours en arrière-plan de mon ordinateur en tant que processus invisible. C'était plus facile que de faire travailler TopShelf pour moi. Quelques tutoriels TopShelf m'ont échoué avant d'écrire ceci avec l'aide d'un code que j'ai trouvé ailleurs. ; P

J'ai également essayé simplement de modifier les paramètres dans Visual Studio> Projet> Propriétés> Application pour lancer en tant qu'application Windows au lieu d'une application console, et quelque chose à propos de mon projet a empêché cela de cacher ma console - peut-être parce que DSharpPlus demande de lancer une console au démarrage . Je ne sais pas. Quelle que soit la raison, cette classe me permet de tuer facilement la console après son apparition.

J'espère que ce magicien aide quelqu'un. ;)

Lucas Jarrett
la source
0

Ecrivez

ProcessStartInfo psi= new ProcessStartInfo("cmd.exe");
......

psi.CreateNoWindow = true;
Navin
la source