2012-03-28 20 views
8

Vorrei essere in grado di scollegare il mio programma dalla console molto simile a wget -b. Un frammento di codice potrebbe essere simileC# close standard out

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.*/ 
} 

Ma System.Console.Out.Close(); non fare la cosa giusta.

Per chiarire, la "cosa giusta" è, quando si esegue questo programma dalla console, il prompt dovrebbe riapparire. Oppure, quando si esegue questo programma da explorer.exe, la finestra della console dovrebbe chiudersi.

Per favore fatemi sapere se non sono chiaro.

+0

solo per essere sicuro, che ho capito la tua domanda: se si digita yourprogram.exe nella finestra di cmd dovrebbe apparire un nuovo. se fai doppio clic sull'applicazione in explorer, vuoi chiudere la console? cosa vuoi fare con la tua applicazione? –

+0

Un'applicazione console senza la console? Non vedo l'ora di vedere la risposta a questo ... –

+1

Se desideri un'applicazione di lunga durata che rimane sullo sfondo, stai cercando un servizio di Windows. Se si desidera avviare periodicamente la propria applicazione, si potrebbe prendere in considerazione l'avvio con l'Utilità di pianificazione. – jlafay

risposta

1

La fonte per wget a cui si fa riferimento è disponibile here. Si noterà che nelle righe mswindows.c 193 - 314 viene implementata una procedura a forcella. Generano una nuova istanza di wget e gli passano gli stessi parametri.

I commenti sono informative, troppo:

Windows non supporta il fork() chiamata; quindi lo simuliamo invocando un'altra copia di Wget con gli stessi argomenti con cui siamo stati invocati.

E sulla linea 102:

In Windows 9x, se ci sono stati lanciati da un processo a 16 bit ... il processo genitore dovrebbe riprendere subito. Sotto NT ... questo è un gesto inutile dato che il genitore aspetterà che terminiamo prima di riprendere.

La risposta breve sembra essere "Non farlo".

+0

Sì, potresti falsificarlo o avvicinarti molto, ma è severamente 'non consigliato' –

+0

Puoi pensare a un'altra implementazione? –

+0

Se non ti dispiace chiederti: qual è lo scopo di stampare qualcosa/restituire qualcosa alla console prima di farlo ... qualsiasi cosa faccia il resto della console? Separare le due metà avrebbe senso? Un servizio in esecuzione, che un componente della riga di comando può inviare e terminare un comando, ha senso? –

1

Sono disponibili 3 canali per qualsiasi app della console in esecuzione: STDIN, STDOUT, STDERR. Tradizionalmente tutti e 3 devono essere chiusi affinché un'app possa rilasciare la console.

In Windows sembra tuttavia esserci un metodo API per farlo: FreeConsole ... e pinvoke.net.

Modifica: un altro post SO dice che non è possibile senza avviare un processo in background: How to make a windowless/command-line application return but continue executing in background? ... In Unix sarebbe sufficiente con un fork();.

+0

Questo non funziona. 'static void Main (string [] args) {System.Console.Out.Close(); System.Console.In.Close(); System.Console.Error.Close(); System.Console.WriteLine ("detatched.");} 'Mostra che la console non è scollegata. –

+0

Ho provato 'FreeConsole'. Sembra * quasi * funzionare. Non riesco più a utilizzare la console per scrivere sullo standard dopo averlo liberato, ma l'interprete dei comandi continua a non recuperare la console. –

+0

@LimitedAtonement hai avviato l'applicazione eseguendo cmd.exe, quindi eseguendo l'applicazione? Per tornare alla shell, è necessaria una copia di cmd.exe connessa alla stessa console. –

0

Per chiarire, la "cosa giusta" è, quando si esegue questo programma dalla console, il prompt dovrebbe riapparire. Oppure, quando si esegue questo programma da explorer.exe, la finestra della console dovrebbe chiudersi.

Non è che si desideri "chiudere la finestra della console", si desidera che non esista. C'è un modo molto semplice per ottenere quello che vuoi: non costruire un'app per console. :-)

Se si costruisce dalla riga di comando, utilizzare CSC /target:winexe .... Questo creerà un programma Windows che non sarà mai associato a nessuna riga di comando.

+0

Non è esattamente il mio intento. Voglio una console per un po ', poi voglio staccarla da essa. Ho modificato la domanda poco fa per chiarire questo requisito. L'esempio di codice potrebbe essere più chiaro ora. –

1

Invece di creare una console app e poi avere problemi con la chiamata a FreeConsole, si potrebbe essere in grado di ottenere ciò che si vuole con la creazione di una normale applicazione di Windows, senza interfaccia grafica, che utilizza AllocConsole/AttachConsole/FreeConsole come necessario.

In questo modo è disponibile un'app che può essere eseguita in background ma che può mostrare e nascondere una finestra della console in base alle esigenze. Anche se per quanto mi ricordo, ci sono alcune differenze tra queste finestre della console e normali comandi di comando di Windows, quindi potrebbe non funzionare per quello che vuoi.

+0

Grazie per la risposta. È certamente un'idea per aprire una nuova finestra della console, ma speravo di interagire solo con la finestra della console esistente. Non penso di avere problemi con 'FreeConsole'; sta agendo come "dovrebbe". Sono a conoscenza di 'AllocConsole', ecc. Il problema è che l'interprete dei comandi (cmd o powershell) attende che il * processo * termini prima di tornare all'interprete dei comandi. Grazie ancora. –