So führen Sie eine C # -Konsolenanwendung mit ausgeblendeter Konsole aus

140

Gibt es eine Möglichkeit, das Konsolenfenster beim Ausführen einer Konsolenanwendung auszublenden?

Ich verwende derzeit eine Windows Forms-Anwendung, um einen Konsolenprozess zu starten, möchte jedoch nicht, dass das Konsolenfenster angezeigt wird, während die Aufgabe ausgeführt wird.

Aaron Thomas
quelle
Versuchen Sie, die Konsolenanwendung von einer geplanten Aufgabe aus auszuführen.

Antworten:

157

Wenn Sie die ProcessStartInfoKlasse verwenden, können Sie den Fensterstil auf ausgeblendet setzen. Bei Konsolenanwendungen (nicht GUI-Anwendungen) müssen Sie CreateNoWindow auf Folgendes setzen 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
quelle
25
Genau das, was ich posten wollte :)
Jon Skeet
74
Heiliger Mist - jemand schneller als Jon! =)
Erik Forbes
75
Ich musste seine Internetverbindung drosseln, um ihn zu schlagen;)
Adam Markowitz
11
Das Aufrufen eines Befehlszeilentools funktionierte nicht. Verwendet yourprocess.StartInfo.CreateNoWindow = true; stattdessen siehe unten.
Christian
12
Versteckt das Konsolenfenster nicht, StartInfo.CreateNoWindow = true ist erforderlich.
Daniel
201

Wenn Sie die Konsolenanwendung geschrieben haben, können Sie sie standardmäßig ausblenden.

Erstellen Sie eine neue Konsolen-App und ändern Sie den Typ "Ausgabetyp" in "Windows-Anwendung" (in den Projekteigenschaften ausgeführt).

Simon
quelle
6
Ich habe versucht, meine eigene Konsole zu verstecken, nicht etwas anderes anzurufen und es dann zu verstecken (wie die akzeptierte Antwort annimmt) - also war dies die beste für mich. Vielen Dank!
iamserious
6
Danke Kumpel ! Das habe ich auch gesucht!
Varun Sharma
3
Die akzeptierte Antwort geht davon aus, dass dies in der Frage angegeben ist.
Aqua
Der einfachste Weg ... hat mir sehr gut gefallen ... wir wollen das Fenster auf keinen Fall zeigen, weil es für mich einen weiteren Prozess starten wird ...
Sai Avinash
1
In diesem Fall werden Probleme mit ProcessStartInfo umgangen, bei denen Sie Benutzeranmeldeinformationen angeben und dieser Benutzer zufällig angemeldet ist oder der aktuelle Benutzer. In dieser Situation wird die CreateNoWindow-Eigenschaft ignoriert, sodass Sie immer ein Konsolenfenster erhalten. Wenn Sie die Konsolen-App auf Windows-Anwendung einstellen, jedoch ohne Fenster, erhalten Sie kein Fenster.
tjmoore
67

Wenn Sie Process Class verwenden, können Sie schreiben

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

Vorher yourprocess.start();und Prozess wird ausgeblendet

Peter Mortensen
quelle
4
Viel Glück, wenn Sie diesen Prozess frühzeitig beenden müssen. Process.Kill wird abrupt beendet. Process.CloseMainWindow schlägt fehl. GenerateConsoleCtrlEvent kann keine Strg + C- oder Strg + Pause an den Prozess senden. WM_CLOSE für alle Thread-Fenster im Prozess schlägt fehl. Es scheint keine Möglichkeit zu geben, einen mit diesen beiden Parameterwerten gestarteten Prozess sauber zu beenden. Siehe meine Frage hier: stackoverflow.com/questions/16139571/…
Triynko
Vielen Dank, das war das einfachste. Auch wenn Sie den Code für die Konsole besitzen (oder deptieren), fand ich dieses Mutex-Beispiel am einfachsten für ein sauberes Herunterfahren. stackoverflow.com/a/31586184/1877412
cbuteau
1
@Triynko: Sie können keinen Prozess sauber beenden, es sei denn, dieser Prozess arbeitet aktiv zusammen. Dies ist keine Frage von Flaggen oder irgendetwas anderem. Es gibt einfach nichts im Betriebssystem, was ein sauberes Herunterfahren auslösen könnte. Die übliche Lösung besteht darin, ein wartbares Kernelobjekt zu verwenden, das im Steuerungsprozess signalisiert wird, wann der Slave-Prozess beendet werden soll. Der Slave-Prozess muss den Status dieses wartbaren Objekts aktiv überwachen und ein sauberes Herunterfahren einleiten, sobald es signalisiert wird.
Unsichtbarer
43

Die einfache Antwort lautet: Gehen Sie zu den Eigenschaften Ihrer Konsolenanwendung (Projekteigenschaften). Ändern Sie auf der Registerkarte "Anwendung" einfach den "Ausgabetyp" in "Windows-Anwendung". Das ist alles.

Cihan
quelle
4
Bullseye. Dies entspricht dem Erstellen einer Windows-Anwendung, die keine Formulare aufruft.
Asche999
1
Dies ist die richtige Antwort. Keiner Ihrer anderen Bandaid-Ansätze. Dies ist die richtige Antwort. Sie möchten, dass Ihre Anwendung niemals eine Konsole öffnet. Außerdem möchten Sie jederzeit ein Formular öffnen können. Sie rufen das Formular einfach an, wenn Sie möchten. Das heißt, unser Formular wird aufgerufen, wenn der Benutzer mit der rechten Maustaste auf das Taskleistensymbol klickt und Einstellungen auswählt. DAS IST DIE RICHTIGE ANTWORT !!!
Bluebaron
20

Du kannst den ... benutzen FreeConsole- API verwenden, um die Konsole vom Prozess zu trennen :

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

(Dies gilt natürlich nur, wenn Sie Zugriff auf den Quellcode der Konsolenanwendung haben.)

Thomas Levesque
quelle
Ich wollte die Konsole nicht zeigen. Während es FreeConsoletut, was sein Name sagt, hindert es Windows nicht daran, die Konsole anzuzeigen, bevor sie aufgerufen wird.
Jader Dias
5
Dann kompilieren Sie das Projekt als Windows-Anwendung, nicht als Konsolenanwendung
Thomas Levesque
1
Für die Aufzeichnung ist dies genau das, was ich brauchte, danke. Es ist auch genau das , was der Titel verlangt :) Also im Interesse anderer Google-Reisender, +1
sehe
3
Darüber hinaus [DllImport("kernel32.dll")] static extern bool AllocConsole();können Sie problemlos mit einer Konsole aus einer Standard-Win32-Anwendung
ausführen
1
Funktioniert für meine .NET Core 2.2-App - wenn jemand speziell danach sucht.
Medismal
7

Wenn Sie an der Ausgabe interessiert sind, können Sie diese Funktion verwenden:

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

Es führt das angegebene Befehlszeilenprogramm aus, wartet auf den Abschluss und gibt die Ausgabe als Zeichenfolge zurück.

JCH2k
quelle
4

Wenn Sie ein Programm erstellen, für das keine Benutzereingaben erforderlich sind, können Sie es jederzeit als Dienst erstellen. Ein Dienst zeigt keine Benutzeroberfläche an.

Chris Bregg
quelle
Wenn Sie den Prozess jedoch nur ausführen möchten, bis er beendet wird, z. B. indem Sie ihn über den Taskplaner aufrufen, ist ein Dienst unpraktisch, da er weiterhin besteht. In einigen Situationen ist es sehr praktisch, den Ausgabetyp in Windows-Anwendung im Vergleich zum alternativen ProcessWindowStyle als versteckt zu ändern.
Subsci
2

Fügen Sie dies Ihrer Klasse hinzu, um die DLL-Datei zu importieren:

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

Und wenn Sie es ausblenden möchten, verwenden Sie diesen Befehl:

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

Und wenn Sie die Konsole zeigen möchten:

var handle = GetConsoleWindow();
ShowWindow(handle, SW_SHOW);
IDK alles
quelle
1
[DllImport ("user32.dll")] statisches externes Bool ShowWindow (IntPtr hWnd, int nCmdShow); [DllImport ("kernel32.dll")] static extern IntPtr GetConsoleWindow (); const int SW_HIDE = 0; const int SW_SHOW = 5;
Soulmachine
1

Ich weiß, dass ich nicht genau beantworte, was Sie wollen, aber ich frage mich, ob Sie die richtige Frage stellen.

Warum benutzt du auch nicht:

  1. Windows-Service
  2. Erstellen Sie einen neuen Thread und führen Sie Ihren Prozess darauf aus

Diese klingen nach besseren Optionen, wenn Sie nur einen Prozess ausführen möchten.

Nathan Koop
quelle
3
Es gibt viele Szenarien, in denen das Starten einer Utility-Konsolenanwendung absolut legitim ist.
Adam Robinson
In meinem Fall ist aufgrund des Client / Server-Modells, an dem die Software, an der ich arbeite, verwendet wird, ein separater Prozess erforderlich.
Aaron Thomas
Es löst nicht immer das Problem, einen neuen Thread zu erstellen. Es gibt Zeiten, in denen Sie das nervige Fenster einfach nicht im Hintergrund sehen möchten. Was ist auch, wenn Sie einen process.start in einer Schleife haben, dann werden Sie keine Arbeit erledigen, wenn Konsolenfenster in Ihrem Gesicht auftauchen.
user890332
1
Ich starte fensterlose Utility-Konsolen-Apps über den Taskplaner. Keine Notwendigkeit für Service und kein übergeordneter Prozess, von dem aus ein Thread gegabelt werden kann. Diese Apps schreiben in das EventLog, wenn zusätzliche Ausgaben erforderlich sind.
Subsci
1

Obwohl andere Antworten hier besagten, dass Sie den "Ausgabetyp" in "Windows-Anwendung" ändern können, beachten Sie bitte, dass dies bedeutet, dass Sie ihn nicht verwenden können, Console.Inda er zu einem NullStreamReader wird.

Console.Outund Console.Errorscheinen aber immer noch gut zu funktionieren.

kjbartel
quelle
2
Sind Sie im Ernst? Warum sollte jemand verwenden, Console.Inwenn es keine Konsole gibt, um etwas einzugeben? Woher soll etwas kommen, über das zugegriffen werden kann Console.In? Das macht überhaupt keinen Sinn. Mit anderen Worten: Es ist völlig klar und logisch , dass Console.Ineine ist NullStreamReaderin diesem Fall.
Robert S.
1
@ Roberts. Eine Pfeife vielleicht. Dh die Ausgabe eines anderen Programms. Das war mein Anwendungsfall, als ich das entdeckte.
Kjbartel
1

Basierend auf der obigen Antwort von Adam Markowitz hat Folgendes für mich funktioniert:

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();
Vulkan Baru
quelle
1

Ich habe eine allgemeine Lösung zu teilen:

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

Nehmen Sie diese Klasse einfach in Ihr Projekt auf und rufen Sie an Magician.DisappearConsole(); .

Eine Konsole blinkt, wenn Sie das Programm durch Klicken starten. Bei der Ausführung an der Eingabeaufforderung verschwindet die Eingabeaufforderung sehr kurz nach der Ausführung.

Ich mache das für einen Discord Bot, der als unsichtbarer Prozess für immer im Hintergrund meines Computers läuft. Es war einfacher, als TopShelf dazu zu bringen, für mich zu arbeiten. Ein paar TopShelf-Tutorials sind fehlgeschlagen, bevor ich dies mit Hilfe von Code geschrieben habe, den ich an anderer Stelle gefunden habe. ; P.

Ich habe auch versucht, die Einstellungen in Visual Studio> Projekt> Eigenschaften> Anwendung einfach so zu ändern, dass sie als Windows-Anwendung anstelle einer Konsolenanwendung gestartet werden. Durch etwas an meinem Projekt konnte meine Konsole dadurch nicht ausgeblendet werden - möglicherweise, weil DSharpPlus beim Start eine Konsole starten muss . Ich weiß es nicht. Was auch immer der Grund sein mag, diese Klasse ermöglicht es mir, die Konsole einfach zu töten, nachdem sie aufgetaucht ist.

Hoffe, dieser Magier hilft jemandem. ;)

Lucas Jarrett
quelle
0

Einfach schreiben

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

psi.CreateNoWindow = true;
Navin
quelle