2009-07-23 6 views
7

私はコンソールアプリケーションをC#で書いています。これはいくつかのデータを処理して結果を出力します。結果が得られるまで、アニメーション(/ - \ |)と進行中のパーセンテージ(xx%)が常に更新されています。出力がリダイレクトされているかどうか確認してください

明らかに、ユーザーがアプリケーションの出力をリダイレクトすると、これは出力がリダイレクトされるテキストファイルに出力されます。可能であれば、私はこれを避けたいと思います。

私のアプリケーションの出力がリダイレクトされているかどうかを検出する方法はありますか? 指定されたパラメータで実行するときに進捗インジケータのみを表示することを検討していますが、誰かが私のために良い答えを得ることを望んでいます。

+0

あなたの質問を3年後に読んで、それを読んだ人がいればどれほど愚かなのかを理解しています...これにアプローチする正しい方法は、デフォルトで進捗バーを表示しないことです。特定のスイッチが使用されているときに表示します。 – Nippysaurus

+0

[Console.Outがファイルにリダイレクトされているかどうかをどのように判断できますか?](http://stackoverflow.com/questions/743885/how-can-i-determine-whether-console-out-has-ファイルにリダイレクトされました) –

答えて

2

できません。リダイレクトされた出力は、実行中のプログラムの範囲外にあります。しかしですが、コマンドラインオプションを追加すると、かなり出力が無効になり、リダイレクトすることもできます。

EDIT:あなたは(今)することができます...以降、.NET 4.5とMatt Brooks' answerを参照してください)。

+0

私が思ったのと同じように。 Nippysaurus

+0

入力がコンソールかどうかによっていくつかのデフォルト設定を推測したいのですが?たとえば、SQLパーサーでは、キーボードからのコマンドを受け入れるときに結果のレコードセットを印刷するのが良いですが、ファイルを解析するときには静かにしてください。あるいは、ファイルへの書き込み時にUnicode BOMを出力したいと思ったらどうしますか?これらの場合に使用すべきパターンは何ですか? – himself

+0

@himself:BOMの作成などの処理をしたい場合は、出力パラメータを尋ねます。 OSによっては、コンソールで実行しているかどうかを検出することができますが、それは控えめに言えば畳み込まれていて、Windows/Cではうまく動作しません。あなたの最も簡単な方法は、 '-q'(静か)または同様のオプションを受け入れることです。あるいは、もしあなたがファイルに書き込むことを可能にしているとしたら、プログラムされた入力を得ていると仮定します。 –

3

コンテンツがリダイレクトされるかどうかを判断するのではなく、Console.WriteLine(またはConsole.Out.WriteLine)を使用して結果を出力し、Console.Error.Writeを使用してステータス更新を行います。画面の出力は正しく表示されますが、テキストファイルには反映されません。

+0

良い考えですが、エラーのないデータをstderrに書き込むのはむしろ間違いです。 – Nippysaurus

+0

誤解を招く、はい、しかし共通の習慣はすべて同じです。 –

5

ネイティブメソッドGetConsoleModeを使用して、stdoutがコンソールに移動するかどうかを確認できます。

この方法はWriteConsoleのためにドキュメントの発言によって提案された:

...出力ハンドルはコンソールハンドルがあるかどうかを判断する(一つの方法は、GetConsoleMode関数を呼び出し、それが成功するかどうかを確認することです) ...

+0

Granntedは、安全でないネイティブメソッドを使用することを意味します...しかし、可能です。 – Stobor

+0

P/Invokeは痛みですが、実行可能に見えます。 –

+0

いくつかのプロパティは 'GetConsoleMode'を呼び出し、' Console.CursorVisible'のような失敗時にスローします。これにより、P/Invokeを使用せずにコンソール出力を確認することができます。 – Medinoc

7

結局のところ、それはすぐにエレガントでクロスプラットフォームな方法で利用できるようになります: link

+0

それはかなりクールです:-) – Nippysaurus

2

おそらく、あなたはこの試みることができます:標準出力がリダイレクトされていない場合は、GetFileType()の出力は0×0002である必要があり

public enum FileType : uint 
{ 
    FILE_TYPE_UNKNOWN = 0x0000, 
    FILE_TYPE_DISK = 0x0001, 
    FILE_TYPE_CHAR = 0x0002, 
    FILE_TYPE_PIPE = 0x0003, 
    FILE_TYPE_REMOTE = 0x8000, 
} 

public enum STDHandle : uint 
{ 
    STD_INPUT_HANDLE = unchecked((uint)-10), 
    STD_OUTPUT_HANDLE = unchecked((uint)-11), 
    STD_ERROR_HANDLE = unchecked((uint)-12), 
} 

[DllImport("Kernel32.dll")] 
static public extern UIntPtr GetStdHandle(STDHandle stdHandle); 
[DllImport("Kernel32.dll")] 
static public extern FileType GetFileType(UIntPtr hFile); 

static public bool IsOutputRedirected() 
{ 
    UIntPtr hOutput = GetStdHandle(STDHandle.STD_OUTPUT_HANDLE); 
    FileType fileType = (FileType)GetFileType(hOutput); 
    if (fileType == FileType.FILE_TYPE_CHAR) 
     return false; 
    return true; 
} 

を。 これは私のために働く。 :)

0

Console.Write("whatever")(およびWriteLine)は、実際にデータをConsole.Outの後ろのストリームに書き込みます。 は、常にコンソール上のプログレスバーを表示し、ファイルに書き込みしない場合は、出力をファイルにリダイレクトされているかどうかに関係なくは、代わりに、エラーストリームを使用します。

Console.Error.Write("<your progress bar>");

アプリケーションのリダイレクトを>演算子(DIR C:\*.*>MORE)との出力は、唯一Console.OutリダイレクトされないConsole.Error

10

の.NET Framework 4.5から以降は、これを検出するために、Console.IsOutputRedirected propertyを使用することができます。

Console.IsErrorRedirectedもあります。

関連する問題