2012-03-28 13 views
8

Me gustaría poder separar mi programa de la consola al igual que wget -b. Un fragmento de código podría ser comoC# cerrar estándar

static void Main(string[] args) 
{ 
    var settings = new Settings(args); 
    if (settings.Background) 
    { 
     /*Tell the user what's going on.*/ 
     System.Console.WriteLine("Detatching from console. The program will still be running."); 
     System.Console.Out.Close(); 
    } 
    /*do work then exit.*/ 
} 

Pero System.Console.Out.Close(); no hacer lo correcto.

Para aclarar, lo "correcto" es que, al ejecutar este programa desde la consola, el mensaje debería volver a aparecer. O bien, al ejecutar este programa desde explorer.exe, la ventana de la consola debe cerrarse.

Háganme saber si no estoy siendo clara.

+0

solo para estar seguro, entendí su pregunta: si escribe yourprogram.exe en la ventana de cmd debería aparecer una nueva. Si hace doble clic en la aplicación en el explorador, ¿quiere que la consola se cierre? ¿Qué quieres hacer con tu aplicación? –

+0

¿Una aplicación de consola sin la consola? No puedo esperar para ver la respuesta a esto ... –

+1

Si quieres una aplicación de larga duración que permanezca en segundo plano, estás queriendo un servicio de Windows. Si solo desea iniciar periódicamente su aplicación, puede considerar iniciarla con el programador de tareas. – jlafay

Respuesta

1

La fuente para wget a la que se refiere está disponible here. Notarás que en mswindows.c líneas 193 - 314, se implementa un procedimiento fork. Generan una nueva instancia de wget y le pasan los mismos parámetros.

Los comentarios son informativos, también:

Windows no admite el tenedor() llamada; así que lo falsificamos al invocar otra copia de Wget con los mismos argumentos con los que fuimos invocados.

Y en la línea 102:

En Windows 9x, si se pusieron en marcha de un proceso de 16 bits ... el proceso padre debe reanudarse de inmediato. Bajo NT ... este es un gesto inútil ya que el padre esperará a que terminemos antes de reanudar.

La respuesta corta parece ser "No hagas eso".

+0

Sí - podría fingir o acercarse mucho, pero es muy estrictamente 'no recomendado' –

+0

¿Puede pensar en otra implementación? –

+0

Si no te molesta que pregunte: ¿para qué sirve imprimir algo/devolver algo a la consola antes de hacer ... lo que sea que haga el resto de la consola? ¿Tendría sentido separar las dos mitades? ¿Tendría sentido un servicio en ejecución, al que un componente de línea de comando pueda enviar un comando y luego terminarlo? –

1

Hay 3 canales abiertos para cualquier aplicación de consola en ejecución: STDIN, STDOUT, STDERR. Tradicionalmente, se deben cerrar los 3 para que una aplicación libere la consola.

En Windows, sin embargo, parece haber un método API para hacerlo: FreeConsole ... y pinvoke.net.

Editar: Otra publicación SO dice que no es posible sin iniciar un proceso en segundo plano: How to make a windowless/command-line application return but continue executing in background? ... En Unix sería suficiente con un fork();.

+0

Eso no funciona. 'static void Main (cadena [] args) {System.Console.Out.Close(); System.Console.In.Close(); System.Console.Error.Close(); System.Console.WriteLine ("detatched.");} 'Muestra que la consola no está separada. –

+0

Probé 'FreeConsole'. Parece * casi * funcionar. Ya no puedo usar la consola para escribir en estándar después de liberarlo, pero el intérprete de comandos aún no recupera la consola. –

+0

@LimitedAtonement ¿inició su aplicación ejecutando cmd.exe y luego ejecutando la aplicación? Para volver al shell, necesitaría una copia de cmd.exe conectada a la misma consola. –

0

Para aclarar, lo "correcto" es que, al ejecutar este programa desde la consola, el mensaje debería volver a aparecer. O bien, al ejecutar este programa desde explorer.exe, la ventana de la consola debe cerrarse.

No es que desee la "ventana de la consola [para] cerrar", quiere que no exista. Hay una forma muy sencilla de obtener lo que desea: no cree una aplicación de consola. :-)

Si compila desde la línea de comando, use CSC /target:winexe .... Esto creará un programa de Windows que nunca se asociará con ninguna línea de comando.

+0

Esa no es exactamente mi intención. Quiero una consola por un tiempo, luego quiero separarme de ella. Edité la pregunta hace un momento para aclarar este requisito. El ejemplo del código podría ser más claro ahora. –

1

En lugar de crear una aplicación de consola y luego tener problemas con la llamada a FreeConsole, usted podría ser capaz de conseguir lo que quiere mediante la creación de una aplicación de Windows normal, sin una interfaz gráfica de usuario, que utiliza AllocConsole/AttachConsole/FreeConsole según sea necesario.

De esta manera tienes una aplicación que se puede ejecutar en segundo plano pero que puede mostrar y ocultar una ventana de consola según sea necesario. Aunque, por lo que recuerdo, existen algunas diferencias entre estas ventanas de consola y las instrucciones de comando normales de Windows, por lo que podría no funcionar para lo que usted desea.

+0

Gracias por la respuesta. Ciertamente, es una idea abrir una nueva ventana de consola, pero esperaba interactuar solo con la ventana de consola existente. No creo que tenga problemas con 'FreeConsole'; está actuando como "debería". Soy consciente de 'AllocConsole', etc. El problema es que el intérprete de comandos (cmd o powershell) espera a que el * proceso * finalice antes de volver al intérprete de comandos. Gracias de nuevo. –