Cómo ejecutar una aplicación de consola C # con la consola oculta

141

¿Hay alguna forma de ocultar la ventana de la consola al ejecutar una aplicación de consola?

Actualmente estoy usando una aplicación Windows Forms para iniciar un proceso de consola, pero no quiero que se muestre la ventana de la consola mientras se ejecuta la tarea.

Aaron Thomas
fuente
intente ejecutar la aplicación de consola desde la tarea programada.

Respuestas:

158

Si está utilizando la ProcessStartInfoclase, puede configurar el estilo de ventana como oculto; en el caso de las aplicaciones de consola (no GUI), debe configurar CreateNoWindow para 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
fuente
26
Justo lo que iba a publicar :)
Jon Skeet
75
Santa mierda, ¡alguien más rápido que Jon! =)
Erik Forbes
75
Tuve que estrangular su conexión a Internet para vencerlo;)
Adam Markowitz
11
No funcionó para invocar una herramienta de línea de comandos. Usó yourprocess.StartInfo.CreateNoWindow = true; en cambio, ver abajo.
Christian
12
No oculta la ventana de la consola, se necesita StartInfo.CreateNoWindow = true.
Daniel
201

Si escribió la aplicación de consola, puede ocultarla de forma predeterminada.

Cree una nueva aplicación de consola y luego cambie el tipo de "Tipo de salida" a "Aplicación de Windows" (hecho en las propiedades del proyecto)

Simón
fuente
66
Intenté ocultar mi propia consola, no llamar a otra cosa y luego ocultarla (como asume la respuesta aceptada), así que esta fue la mejor para mí. ¡Gracias!
iamserious
66
Gracias amigo ! ¡Esto es lo que estaba buscando también!
Varun Sharma
3
La respuesta aceptada asume eso porque se indica en la pregunta.
aqua
de la manera más simple ... realmente me gustó ... ciertamente no queremos mostrar la ventana porque va a lanzar otro proceso para mí ...
Sai Avinash
1
Este soluciona problemas con ProcessStartInfo donde especifica las credenciales de usuario y ese usuario está conectado o es el usuario actual. En esa situación, la propiedad CreateNoWindow se ignora para que siempre obtenga una ventana de consola. Al configurar la aplicación de consola en Aplicación de Windows pero sin una ventana, no se obtiene ninguna ventana.
tjmoore
67

Si está utilizando Process Class, puede escribir

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

antes yourprocess.start();y el proceso estará oculto

Peter Mortensen
fuente
44
Buena suerte si tienes que detener ese proceso temprano. Proceso La muerte termina abruptamente. Process.CloseMainWindow falla. GenerateConsoleCtrlEvent no puede enviar ctrl + c o ctrl + break al proceso. WM_CLOSE para todas las ventanas de subprocesos en el proceso falla. Parece que no hay forma de finalizar limpiamente un proceso iniciado con esos dos valores de parámetros. Vea mi pregunta aquí: stackoverflow.com/questions/16139571/…
Triynko
Gracias toneladas, esta fue la más simple. Además, si posee (o departamento) el código para la consola, este ejemplo de mutex es el más fácil para un apagado limpio. stackoverflow.com/a/31586184/1877412
cbuteau
1
@Triynko: No puede finalizar limpiamente ningún proceso, a menos que ese proceso coopere activamente. No se trata de banderas ni de nada más. Simplemente no hay nada en el sistema operativo que pueda desencadenar un apagado limpio. La solución común aquí es usar un objeto de núcleo esperable, que se señala en el proceso de control, cuando el proceso esclavo debe terminar. El proceso esclavo necesita monitorear activamente el estado de este objeto esperable e iniciar un apagado limpio una vez que se lo indique.
Inspeccionable el
43

La respuesta simple es: Vaya a las propiedades de la aplicación de su consola (propiedades del proyecto). En la pestaña "Aplicación", simplemente cambie el "Tipo de salida" a "Aplicación de Windows". Eso es todo.

Cihan
fuente
44
Diana. Esto es lo mismo que crear una aplicación de Windows que no llame a ningún formulario.
cenizas999
1
Esta es la respuesta correcta. Ninguno de tus otros acercamientos curita. Esta es la respuesta CORRECTA real. En primer lugar, desea que su aplicación nunca abra una consola. Además, desea poder abrir un formulario en cualquier momento. Entonces simplemente llame al formulario cuando lo desee. es decir, se llama a nuestro formulario cuando el usuario hace clic derecho en el icono de la bandeja del sistema y selecciona las preferencias. ¡¡¡ESTA ES LA RESPUESTA CORRECTA!!!
Bluebaron
20

Puede usar la API de FreeConsole para separar la consola del proceso:

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

(por supuesto, esto solo es aplicable si tiene acceso al código fuente de la aplicación de consola)

Thomas Levesque
fuente
No quería mostrar la consola. Si bien FreeConsolehace lo que dice su nombre, no impide que Windows muestre la consola antes de que se llame.
Jader Dias
55
Luego compile el proyecto como una aplicación de Windows, no una aplicación de consola
Thomas Levesque
1
Para el registro, esto es exactamente lo que necesitaba, gracias. También es exactamente lo que pide el título :) Entonces, en interés de otros viajeros de Google, +1
sehe
3
Además, le [DllImport("kernel32.dll")] static extern bool AllocConsole();permite ejecutar fácilmente con una consola desde una aplicación Win32 estándar
consulte el
1
Funciona para mi aplicación .NET Core 2.2, si alguien está buscando esto específicamente.
Medismal
7

Si está interesado en la salida, puede usar esta función:

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

Ejecuta el programa de línea de comando dado, espera a que termine y devuelve el resultado como una cadena.

JCH2k
fuente
4

Si está creando un programa que no requiere la intervención del usuario, siempre puede crearlo como un servicio. Un servicio no mostrará ningún tipo de interfaz de usuario.

Chris Bregg
fuente
Pero si todo lo que desea hacer es ejecutar el proceso hasta que finalice, por ejemplo, al llamarlo desde el Programador de tareas, entonces un servicio es inconveniente ya que continúa existiendo. En algunas situaciones, es muy conveniente cambiar el Tipo de salida a la Aplicación de Windows en comparación con el ProcessWindowStyle alternativo como oculto.
subsci
2

Agregue esto a su clase para importar el archivo 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;

Y luego, si quieres ocultarlo, usa este comando:

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

Y si quieres mostrar la consola:

var handle = GetConsoleWindow();
ShowWindow(handle, SW_SHOW);
IDK cualquier cosa
fuente
1
[DllImport ("user32.dll")] ShowWindow externo estático bool (IntPtr hWnd, int nCmdShow); [DllImport ("kernel32.dll")] estático externo IntPtr GetConsoleWindow (); const int SW_HIDE = 0; const int SW_SHOW = 5;
soulmachine
1

Sé que no estoy respondiendo exactamente lo que quieres, pero me pregunto si estás haciendo la pregunta correcta.

¿Por qué no usas tampoco:

  1. servicio de windows
  2. crea un nuevo hilo y ejecuta tu proceso en ese

Esas suenan como mejores opciones si todo lo que quieres es ejecutar un proceso.

Nathan Koop
fuente
3
Hay muchos escenarios en los que el lanzamiento de una aplicación de consola de utilidad es perfectamente legítimo.
Adam Robinson
En mi caso, es necesario un proceso separado debido al modelo de cliente / servidor que utiliza el software en el que estoy trabajando.
Aaron Thomas
No siempre resuelve el problema crear un nuevo hilo. Hay momentos en los que simplemente no quieres la molesta ventana de fondo. Además, ¿qué pasa si tiene un proceso? Comience en un bucle, entonces no realizará ningún trabajo cuando las ventanas de la consola aparezcan en su cara.
user890332
1
Lanzo aplicaciones de consola de utilidad sin ventanas desde el Programador de tareas. Sin necesidad de servicio, y sin proceso padre desde el que bifurcar un hilo. Estas aplicaciones escriben en EventLog si se necesita una salida adicional.
subsci
1

Aunque, como otras respuestas aquí han dicho, puede cambiar el "Tipo de salida" a "Aplicación de Windows", tenga en cuenta que esto significa que no puede usarlo, Console.Inya que se convertirá en un NullStreamReader.

Console.Outy Console.Errorparece que todavía funcionan bien sin embargo.

kjbartel
fuente
2
¿En serio? ¿Por qué alguien usaría Console.Incuando no hay una consola para ingresar algo? ¿De dónde debe venir algo de lo que se puede acceder Console.In? Esto no tiene ningún sentido en absoluto. En otras palabras: es totalmente obvio y lógico que Console.Insea ​​un NullStreamReaderen este caso.
Robert S.
1
@RobertS. Una pipa tal vez. Es decir, la salida de otro programa. Ese fue mi caso de uso cuando descubrí esto.
kjbartel
1

Basado en la respuesta de Adam Markowitz anterior, lo siguiente funcionó para mí:

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
fuente
1

Tengo una solución general para compartir:

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

Simplemente incluya esta clase en su proyecto y llame Magician.DisappearConsole();.

Una consola parpadeará cuando inicies el programa haciendo clic en ella. Cuando se ejecuta desde el símbolo del sistema, el símbolo del sistema desaparece poco después de la ejecución.

Hago esto para un Discord Bot que se ejecuta para siempre en el fondo de mi computadora como un proceso invisible. Fue más fácil que hacer que TopShelf funcione para mí. Un par de tutoriales de TopShelf me fallaron antes de escribir esto con ayuda del código que encontré en otro lugar. ;PAGS

También intenté simplemente cambiar la configuración en Visual Studio> Proyecto> Propiedades> Aplicación para iniciar como una aplicación de Windows en lugar de una aplicación de consola, y algo sobre mi proyecto evitó que esto ocultara mi consola, tal vez porque DSharpPlus exige iniciar una consola al inicio . No lo sé. Cualquiera sea la razón, esta clase me permite matar fácilmente la consola después de que aparezca.

Espero que este mago ayude a alguien. ;)

Lucas Jarrett
fuente
0

Solo escribe

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

psi.CreateNoWindow = true;
Navin
fuente