Come eseguire un'applicazione console C # con la console nascosta


141

C'è un modo per nascondere la finestra della console quando si esegue un'applicazione console?

Attualmente sto usando un'applicazione Windows Form per avviare un processo della console, ma non voglio che la finestra della console venga visualizzata mentre l'attività è in esecuzione.


prova a eseguire l'applicazione console dall'attività pianificata.

Risposte:


158

Se si utilizza la ProcessStartInfoclasse, è possibile impostare lo stile della finestra su nascosto - nel caso di applicazioni console (non GUI), è necessario impostare CreateNoWindow su 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

26
Proprio quello che stavo per pubblicare :)
Jon Skeet,

75
Santa merda - qualcuno più veloce di Jon! =)
Erik Forbes,

75
Ho dovuto limitare la sua connessione a Internet per batterlo;)
Adam Markowitz,

11
Non ha funzionato per invocare uno strumento da riga di comando. Usato yourprocess.StartInfo.CreateNoWindow = true; invece, vedi sotto.
Christian,

12
Non nasconde la finestra della console, è richiesto StartInfo.CreateNoWindow = true.
Daniel,

201

Se hai scritto l'applicazione console, puoi renderla nascosta per impostazione predefinita.

Crea una nuova app console, quindi modifica il tipo "Tipo di output" in "Applicazione Windows" (fatto nelle proprietà del progetto)


6
Stavo cercando di nascondere la mia console, non chiamare qualcos'altro e quindi nasconderlo (come presuppone la risposta accettata) - quindi questa è stata la migliore per me. Grazie!
iamserious

6
Grazie compagno ! Questo è quello che cercavo anch'io!
Varun Sharma,

3
La risposta accettata presuppone che sia indicata nella domanda.
acqua

il modo più semplice ... mi è piaciuto molto ... di certo non vogliamo mostrare la finestra perché avvierà un altro processo da parte mia.
Sai Avinash,

1
Questo risolve i problemi con ProcessStartInfo in cui si specificano le credenziali dell'utente e l'utente che ha effettuato l'accesso o l'utente corrente. In tale situazione, la proprietà CreateNoWindow viene ignorata in modo da ottenere sempre una finestra della console. Impostando l'app console su Applicazione Windows ma senza una finestra, non si ottiene alcuna finestra.
tjmoore,

67

Se si utilizza la classe di processo, è possibile scrivere

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

prima yourprocess.start();e il processo sarà nascosto


4
Buona fortuna se devi interrompere questo processo in anticipo. Process.Kill termina bruscamente. Process.CloseMainWindow ha esito negativo. GenerateConsoleCtrlEvent non riesce a inviare ctrl + c o ctrl + break al processo. WM_CLOSE a tutte le finestre del thread nel processo non riesce. Sembra che non ci sia modo di terminare in modo chiaro un processo avviato con quei due valori di parametro. Vedere la mia domanda qui: stackoverflow.com/questions/16139571/...
Triynko

Grazie mille è stato il più semplice. Inoltre, se possiedi (o approfondisci) il codice per la console, ho trovato questo esempio di mutex come il più semplice per l'arresto pulito. stackoverflow.com/a/31586184/1877412
cbuteau

1
@Triynko: non è possibile interrompere in modo chiaro alcun processo, a meno che tale processo non coopera attivamente. Non si tratta di bandiere o altro. Non c'è proprio nulla nel sistema operativo che possa innescare un arresto pulito. La soluzione comune qui è usare un oggetto kernel attendibile, che è segnalato nel processo di controllo, quando il processo slave dovrebbe terminare. Il processo slave deve monitorare attivamente lo stato di questo oggetto attendibile e avviare l'arresto pulito una volta segnalato.
Probabile

43

La semplice risposta è che: vai alle proprietà dell'app della tua console (proprietà del progetto). Nella scheda "Applicazione", modifica "Tipo di output" in "Applicazione Windows". È tutto.


4
Bullseye. Ciò equivale a creare un'applicazione Windows che non chiama alcun modulo.
ashes999,

1
Questa è la risposta corretta Nessuno dei tuoi altri approcci bandaid. Questa è la vera risposta GIUSTA. In primo luogo, l'applicazione non deve mai aprire una console. Inoltre, vuoi essere in grado di aprire un modulo in qualsiasi momento. Quindi basta chiamare il modulo quando vuoi. vale a dire che il nostro modulo viene chiamato quando l'utente fa clic con il tasto destro sull'icona della barra delle applicazioni e seleziona le preferenze. QUESTA È LA RISPOSTA ESATTA!!!
Bluebaron,

20

Puoi usare l' API di FreeConsole per staccare la console dal processo:

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

(ovviamente questo è applicabile solo se si ha accesso al codice sorgente dell'applicazione console)


Volevo non mostrare la console. Mentre FreeConsolefa quello che dice il suo nome, non impedisce a Windows di mostrare la console prima che venga chiamata.
Jader Dias,

5
Quindi compilare il progetto come un'applicazione Windows, non come un'applicazione console
Thomas Levesque,

1
Per la cronaca, questo è esattamente ciò di cui avevo bisogno, grazie. È anche esattamente ciò che il titolo richiede :) Quindi, nell'interesse di altri viaggiatori di Google, +1
vedi

3
Inoltre, [DllImport("kernel32.dll")] static extern bool AllocConsole();consente di eseguire facilmente con una console da un'applicazione Win32 standard
esempio l'

1
Funziona con la mia app .NET Core 2.2, se qualcuno lo sta cercando in modo specifico.
Medismal

7

Se sei interessato all'output, puoi utilizzare questa funzione:

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

Esegue il programma della riga di comando specificato, attende che termini e restituisce l'output come stringa.


4

Se stai creando un programma che non richiede l'input dell'utente, puoi sempre crearlo come servizio. Un servizio non mostrerà alcun tipo di interfaccia utente.


Ma se tutto ciò che vuoi fare è eseguire il processo fino a quando non termina, ad es. Chiamandolo dall'Utilità di pianificazione, un servizio è scomodo in quanto continua ad esistere. In alcune situazioni è molto comodo cambiare il Tipo di output in Applicazione Windows rispetto a ProcessWindowStyle alternativo come nascosto.
subsci

2

Aggiungi questo alla tua classe per importare il file 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;

E poi se vuoi nasconderlo usa questo comando:

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

E se vuoi mostrare la console:

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

1
[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;
soulmachine,

1

So che non sto rispondendo esattamente a quello che vuoi, ma mi chiedo se stai facendo la domanda giusta.

Perché non usi neanche:

  1. servizio di windows
  2. crea un nuovo thread ed esegui il tuo processo su quello

Sembrano opzioni migliori se tutto ciò che vuoi è eseguire un processo.


3
Esistono molti scenari in cui il lancio di un'applicazione della console di utilità è perfettamente legittimo.
Adam Robinson,

Nel mio caso è necessario un processo separato a causa del modello client / server utilizzato dal software su cui sto lavorando.
Aaron Thomas,

Non sempre risolve il problema per creare un nuovo thread. Ci sono momenti in cui non vuoi che la fastidiosa finestra sullo sfondo. Inoltre, se avessi un process.start in un ciclo, non otterrai alcun lavoro man mano che le finestre della console si apriranno in faccia.
user890332

1
Avvio app per console di utilità senza finestre dall'Utilità di pianificazione. Nessuna necessità di assistenza e nessun processo parent da cui eseguire il fork di un thread. Queste app scrivono su EventLog se sono necessari ulteriori output.
subsci

1

Sebbene come altre risposte qui abbiano detto che è possibile modificare il "Tipo di output" in "Applicazione Windows", tenere presente che ciò significa che non è possibile utilizzare Console.Inin quanto diventerà un NullStreamReader.

Console.Oute Console.Errorsembra comunque funzionare bene.


2
Sei serio? Perché qualcuno dovrebbe usare Console.Inquando non c'è una console per inserire qualcosa? Da dove dovrebbe venire qualcosa a cui è possibile accedere Console.In? Questo non ha alcun senso. In altre parole: E 'assolutamente evidente e logico che Console.Inè NullStreamReaderin questo caso.
Robert S.

1
@RobertS. Forse una pipa. Cioè l'output di un altro programma. Quello era il mio caso d'uso quando l'ho scoperto.
kjbartel,

1

Sulla base della risposta di Adam Markowitz sopra, il seguente ha funzionato per me:

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

1

Ho una soluzione generale da condividere:

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

Includi questa classe nel tuo progetto e chiama Magician.DisappearConsole();.

Una console lampeggerà quando avvierai il programma facendo clic su di esso. Quando si esegue dal prompt dei comandi, il prompt dei comandi scompare molto poco dopo l'esecuzione.

Lo faccio per un Discord Bot che funziona per sempre sullo sfondo del mio computer come un processo invisibile. È stato più facile che far funzionare TopShelf per me. Un paio di tutorial su TopShelf mi hanno deluso prima di scriverlo con l'aiuto del codice che ho trovato altrove. ; P

Ho anche provato semplicemente a modificare le impostazioni in Visual Studio> Progetto> Proprietà> Applicazione da avviare come Applicazione Windows anziché come Applicazione Console, e qualcosa sul mio progetto ha impedito a questo di nascondere la mia console, forse perché DSharpPlus richiede di avviare una console all'avvio . Non lo so. Qualunque sia il motivo, questa classe mi permette di uccidere facilmente la console dopo che è stata visualizzata.

Spero che questo Mago aiuti qualcuno. ;)


0

Scrivi e basta

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

psi.CreateNoWindow = true;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.