2009-04-13 130 views
15

如果我的程序正在打印到控制檯,我按照Console.WindowWidth通過插入換行符以某種方式執行換行操作 - 並且此功能完美無缺。如何確定Console.Out是否已被重定向到文件?

但是,如果程序的輸出重定向到一個文件或另一個程序,我希望它跳過單詞換行。我怎麼能檢測到這種情況?

Console.WindowWidth在這兩種情況下返回相同的數字。

Bonus點如果解決方案可以區分重定向Console.Out和重定向Console.Error。

+0

[檢查輸出是否重定向]的可能重複(http://stackoverflow.com/questions/1169591/check-if-output-is-redirected) –

回答

11

p/invoke GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)),或者調用一個無害的控制檯功能,如GetConsoleScreenBufferInfo來檢查無效的句柄錯誤。如果您想了解標準錯誤,請使用STD_ERROR_HANDLE。我相信你甚至可以比較GetStdHandle(STD_OUTPUT_HANDLE)GetStdHandle(STD_ERROR_HANDLE)返回的句柄來檢測諸如2>&1之類的東西。

+0

是的,與基於反射的東西完美結合,更具前瞻性。謝謝! –

0

爲什麼重定向文件中的輸出包裝?控制檯所做的包裝不是通過換行符。換句話說,這串:

你好我的名字叫安德魯野兔

將包裹在一個瘦小的控制檯這樣的:

你好我的南
e是安德魯
野兔

但如果您要重定向輸出到它會被寫成這樣一個文件:

你好我的名字叫安德魯野兔

因爲有輸出沒有真正的換行符。

+0

確切地說 - 在一個皮包骨架的控制檯中,它將被包裹在一個蹩腳的辦法。這就是爲什麼在輸出到控制檯之前我們正在包裝自己(通過插入換行符和適當的縮進)。 很明顯,這種方法也包含重定向的輸出,這正是我們試圖避免的。 –

+0

重寫使這個更清晰。 –

8

雖然這是一個小的黑幕,可能是不能保證的工作,你可以試試這個:當控制檯重定向

bool isRedirected; 

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

調用CursorVisible拋出異常。

+0

似乎適用於標準輸出。當只有stderr,只有stdout或兩者都重定向時,不提供區分。儘管如此,仍然可以用於某些用例。 –

+0

當stdout被重定向時,它總是爲我工作,我想是真的唯一一個重要的東西,對吧? –

2

你需要使用反射 - 有點髒兮兮的,但下面的工作:

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

您如何確保它能在.NET的下一個版本中運行? :) – ibz

+0

爲什麼投票下來?這是迄今爲止唯一可以解決的解決方案... –

+0

這就是爲什麼它有點gr。。但它是唯一的選擇。 –

0

不要那樣做!只需傳遞一個額外的命令行參數,指定要應用的格式。它更簡單,更清晰,並且更容易理解將使用您的應用的人員和處理您的代碼的人員。

+2

我不同意。程序應該儘可能大地考慮事情,而不是每次都要求用戶。 –

+0

也不贊同。看看git的行爲。像'git diff'這樣的命令可以通過少量和某種顏色化器來管道,除非它們被傳送或重定向到一個文件。 –

9

.NET 4.5增加了Console.IsOutputRedirectedConsole.IsErrorRedirected

相關問題