2009-04-13 12 views
15

Se il mio programma stampa sulla console, eseguo il word-wrapping in un certo modo in base a Console.WindowWidth inserendo newline - e questo funziona perfettamente.Come posso determinare se Console.Out è stato reindirizzato a un file?

Tuttavia, se l'output del programma viene reindirizzato su un file o su un altro programma, desidero che salti il ​​word-wrapping. Come posso rilevare quando questo è il caso?

Console.WindowWidth restituisce lo stesso numero in entrambi i casi.

Bonus punti se la soluzione può distinguere Console reindirizzata. Fuori da Console.Error reindirizzato.

+0

possibile duplicato di [Controllare se l'output viene reindirizzato] (http://stackoverflow.com/questions/1169591/check-if-output-is-redirect) –

risposta

11

p/invoke GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) o chiamare una funzione di console innocua come GetConsoleScreenBufferInfo per verificare l'errore di handle non valido. Se si desidera conoscere l'errore standard, utilizzare STD_ERROR_HANDLE. Credo che sia possibile anche confrontare le maniglie restituite da GetStdHandle(STD_OUTPUT_HANDLE) e GetStdHandle(STD_ERROR_HANDLE) per rilevare elementi come 2>&1.

+0

Sì, funziona perfettamente e più a prova di futuro di materiale basato sulla riflessione. Grazie! –

0

Perché l'ouput si avvolge nel file reindirizzato? Il wrapping che fa la console non è tramite interruzioni di riga. In altre parole questa stringa:

ciao il mio nome è Andrew Hare

sarebbe avvolgere in una console magro come questo:

ciao il mio nom
E è Andrew
Hare

ma se si dovesse reindirizzare l'output in un file che sarebbe stato scritto così:

ciao il mio nome è Andrew Hare

poiché non ci sono vere e proprie interruzioni di linea in uscita.

+0

Esatto - in una console magro sarebbe avvolto in un schifoso modo.È per questo che ci stiamo avvolgendo (inserendo newline e indentazione appropriata) prima di passare alla console. Ovviamente questo approccio avvolge anche l'output reindirizzato, che è quello che stiamo cercando di evitare. –

+0

Ristrutturato per rendere più chiaro questo. –

8

Mentre questo è un po 'ombroso e probabilmente non è garantito per funzionare, si può provare questo:

bool isRedirected; 

try 
{ 
    isRedirected = Console.CursorVisible && false; 
} 
catch 
{ 
    isRedirected = true; 
} 

Calling CursorVisible genera un'eccezione quando la console viene reindirizzato.

+0

Sembra funzionare per lo stdout. Non fornisce alcuna distinzione tra casi in cui solo stderr, solo stdout o entrambi vengono reindirizzati. Comunque va bene per alcuni casi d'uso però. –

+0

Ha sempre funzionato per me quando lo stdout è stato reindirizzato, cosa che immagino sia davvero l'unico che conterebbe, giusto? –

2

È necessario utilizzare riflessione - un po 'sporca, ma il seguente funzionerà:

static bool IsConsoleRedirected() 
{ 
    var writer = Console.Out; 
    if (writer == null || writer.GetType().FullName != "System.IO.TextWriter+SyncTextWriter") return true; 
    var fld = writer.GetType().GetField ("_out", BindingFlags.Instance | BindingFlags.NonPublic); 
    if (fld == null) return true; 
    var streamWriter = fld.GetValue (writer) as StreamWriter; 
    if (streamWriter == null) return true; 
    return streamWriter.BaseStream.GetType().FullName != "System.IO.__ConsoleStream"; 
} 
+0

E come ci si assicura che funzionerà anche nella prossima versione di .NET? :) – ibz

+0

Perché il voto basso? È l'unica soluzione suggerita finora che funzionerà ... –

+0

Ecco perché è un po 'spiacevole. Ma è l'unica opzione. –

0

non lo fanno! Basta passare un parametro della riga di comando aggiuntivo che specifica la formattazione che si desidera applicare. È più semplice, più pulito e più facile da capire sia dalle persone che useranno la tua app sia dalle persone che lavoreranno sul tuo codice.

+2

Non sono d'accordo. I programmi dovrebbero capire le cose da soli nella misura più ampia possibile e non chiedere all'utente ogni volta. –

+0

Anche in disaccordo. Guarda come si comporta git. Comandi come 'git diff' pipe through less e qualche tipo di colorizer a meno che non vengano reindirizzati o reindirizzati su un file. –

9

.NET 4.5 aggiunge Console.IsOutputRedirected e Console.IsErrorRedirected.

Problemi correlati