2009-04-13 12 views
16

コンソールアプリケーションまたはWindowsアプリケーションから呼び出されているかどうかをコードライブラリが自動的に検出する方法はありますか?私はライブラリがコンソールウィンドウから呼び出されている場合はWindowsイベントログに報告しないでくださいが、代わりにコンソールウィンドウに報告したいと思います。ただし、コンソールウィンドウ内から実行されていない場合は、Windowsイベントログに報告する必要があります。コンソールで実行しているかどうかを検出するには

私はロギングコンポーネントにログターゲットを渡す必要があると思っていましたが、ネイティブでこれら2つのターゲットを自動的に処理できるのであればうまくなります。私はまだlog4netのような広範なものを必要としません。実際には、データベース/ファイルやその他の未知のログ記録のログをサポートする必要がある場合は、そのような解決策をお勧めします。今のところ、私のコンポーネントが環境を自動検出し、環境に応じてコンソールまたはイベントログにログするだけで十分です。

答えて

8

アーキテクチャ上、ロギングコンテキストをライブラリコンポーネントに渡すことは正しい選択です。ライブラリは、実行されている環境に関する多くのコンテキストを認識しているわけではありません。

これら2つの特殊なケースをライブラリ内でネイティブにサポートしたいので、私は統合アプローチを提案します。

  1. 発信者が制御する、より一般化されたロギングエントリポイント/ノブを作成します。
  2. 自動的にサポートするケースの一般化されたエントリポイント/ノブを自動的に設定する別のエントリポイント/ノブを作成します。

でも、あなたの説明によればそれは複雑すぎるようです。あなたのコンソールアプリケーションが適切なTraceListenerをコンソールに追加する適切なTraceListenersをコンソールで使い、コンソール以外のアプリケーションが適切なEventLog TraceListenerを追加してWindowsのイベントログに出力するようにしましたか?これには、外部の依存関係(例えば、log4net)を想定せずに、組み込みの.netロギングのサポートすべてでうまく動作するという追加の利点があります。

+0

正直言って、私は今までのログのやり方ではあまり実験をしていません。実際には、あらかじめ決められたいくつかの場所の1つにログオンする必要がありました。その結果、私はTraceListenersを実験したことはありません...これは変更しようとしています。ありがとう、+1 – BenAlabaster

+0

良い契約、私は助けることができてうれしい! TraceListenerルール。 :D –

1

この質問のバリアントは以前に尋ねられました。即ちhere及びhereである。

「 ソリューションは があなたを呼んでいるかを把握するためにリフレクションを使用して2つのオプション

  • に煮詰めるように見えます。
  • コンソールアプリケーションの場合は、 コンソールにtry-catch ブロックを呼び出し、失敗したか、または が成功したかどうかを確認します。

自分のライブラリにインターフェイスをエクスポートすることをお勧めします。インタフェースには、呼び出し元の型を返す関数またはプロパティがあります。呼び出し元のオブジェクトには、インタフェースを実装するクラスがあり、その型を返します。複雑さが懸念されるので、あなたがインターフェイスに配置することによって幾分それを制御することができます。

アプリケーションがライブラリに登録されていない場合は、エラーを投げたり、自動検出のスキームを試してみることができます。

インターフェイスを使用してエラーをスローすると、ライブラリを使用してプログラマが明示的に何を期待しているかを明示的に指定しています。 2つの間の相互作用はインタフェースによって定義されます。

さらに、ユーザとして、私の呼び出し元のバイナリがいくつかの不思議なルールセットではなくライブラリとどのようにやりとりするかを選択するため、対話は自動スキームよりも柔軟性があります。

0

私はそれがちょっとハックだと知っていますが、Console.Readを呼び出すと、コンソールがないときに例外がスローされます。

bool isConsole = true; 
try 
{ 
    isconsole = Console.CursorLeft >= int.MinValue; 
} 
catch(IOException) 
{ 
    // Try to attach to parent process's console window 
    isConsole = AttachConsole(0xFFFFFFFF); 
} 

... 

[DllImport("kernel32", SetLastError = true)] 
private static extern bool AttachConsole(uint dwProcessId); 

これは副作用であるため、信頼性の高い検出方法ではない可能性がありますが、今のところ機能します。

+1

また、実行する前にガベージ文字を入力する必要がありますか?私は、別の静的コンソールメソッドがユーザーとのやりとりなしで同じ影響を及ぼさないのだろうかと思います。 –

6

「Console.Title」はWindowsアプリケーションの空の文字列になり、自動的にコンソールアプリケーションに設定されることがわかりました。

まだハックですが。

関連する問題