Suprimir la ventana de comandos de la aplicación de línea de comandos iniciado con .NET
-
18-09-2019 - |
Pregunta
Tengo un módulo que tiene que ejecutar un pequeño programa de línea de comandos .Net para comprobar si hay actualizaciones. Todo está funcionando muy bien, sin embargo tengo problemas para suprimir la salida de símbolo del sistema se muestre.
La aplicación tiene su propio formulario de Windows que aparece si se detecta una actualización. La actualización debe ejecutarse como una aplicación independiente debido al hecho de que se requiere un contexto de ejecución diferente de la DLL que se lanza desde.
string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\" + AUTO_UPDATE_EXENAME;
updater.StartInfo.FileName = path;
updater.StartInfo.Arguments = AUTO_UPDATE_PARAMETERS;
updater.StartInfo.CreateNoWindow = false;
updater.StartInfo.UseShellExecute = false;
updater.StartInfo.RedirectStandardOutput = true;
updater.StartInfo.WorkingDirectory = path;
updater.Start();
He probado la mayoría de todas las diferentes combinaciones de trabajo de CreateNoWindow
, UseShellExecute
y RedirectStandardOutput
y cada uno de ellos da como resultado que el cuadro negro molesto apareciendo. La aplicación no escribir en la salida estándar, pero yo sólo uso que para la depuración y el usuario no debe ver realmente el texto que genera.
Supuestamente CreateNoWindow
y / o RedirectStandardOutput
deben impedir que la caja apareciendo, pero sin que importa cómo configurar estas variables.
Solución
Configurar la aplicación de línea de comandos a una aplicación de Windows Forms, pero no abra un formulario cuando se ejecuta, como lo haría normalmente.
Otros consejos
Puede ocultar la ventana en el arranque de la siguiente manera:
using System.Runtime.InteropServices;
namespace MyConsoleApp {
class Program {
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[STAThread()]
static void Main(string[] args)
{
Console.Title = "MyConsoleApp";
if (args.StartWith("-w"))
{
// hide the console window
setConsoleWindowVisibility(false, Console.Title);
// open your form
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run( new frmMain() );
}
// else don't do anything as the console window opens by default
}
public static void setConsoleWindowVisibility(bool visible, string title)
{
//Sometimes System.Windows.Forms.Application.ExecutablePath works
// for the caption depending on the system you are running under.
IntPtr hWnd = FindWindow(null, title);
if (hWnd != IntPtr.Zero)
{
if (!visible)
//Hide the window
ShowWindow(hWnd, 0); // 0 = SW_HIDE
else
//Show window again
ShowWindow(hWnd, 1); //1 = SW_SHOWNORMA
}
}
}
}
El siguiente es un ejemplo de código que interroga al MAC en la conexión activa, se trata de una aplicación de consola, no hay necesidad de hacer de esto una forma de Windows ...
public class TestARP { private StringBuilder sbRedirectedOutput = new StringBuilder(); public string OutputData { get { return this.sbRedirectedOutput.ToString(); } } // Asynchronous! public void Run() { System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo(); ps.FileName = "arp"; ps.ErrorDialog = false; ps.Arguments = "-a"; ps.CreateNoWindow = true; // comment this out ps.UseShellExecute = false; // true ps.RedirectStandardOutput = true; // false ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // comment this out using (System.Diagnostics.Process proc = new System.Diagnostics.Process()) { proc.StartInfo = ps; proc.Exited += new EventHandler(proc_Exited); proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived); proc.Start(); proc.WaitForExit(); proc.BeginOutputReadLine(); // Comment this out } } void proc_Exited(object sender, EventArgs e) { System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended"); } void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e) { if (e.Data != null) this.sbRedirectedOutput.Append(e.Data + Environment.NewLine); } }
Ahora, observe el método Run
, es decir en modo asíncrono, y se ejecuta como una sola ventana de la consola - de hecho una aplicación de consola normal, sin ninguna ventana adicional que se levante, notar los comentarios, si tuviera que cambiar esas líneas, se convierte en un proceso síncrono de los bombardeos a cabo, muy rápidamente, se dará cuenta de que esta consola creará otra ventana con la salida del comando arp
. Debido a que es en modo asíncrono, la salida se le redirecciona a un controlador de eventos, que rellena los datos en la instancia StringBuilder
para su posterior procesamiento ...
Espero que esta ayuda, Atentamente, Tom.