DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

TraceやDebugのWriteメソッドでファイルに出力する

TraceクラスのWriteメソッド(または、WriteLine、WriteIf、WriteLineIfなどのメソッド)はデフォルトでは出力ウィンドウだけにメッセージを出力します。ここでは、これをファイルにも出力する方法を紹介します。

なお、後述しますが、ここで紹介している方法はDebugクラスのWriteメソッドでも有効です。

DefaultTraceListener.LogFileNameプロパティを使用する方法

簡単な方法は、DefaultTraceListenerクラスLogFileNameプロパティに出力ファイル名を指定する方法です。Trace.ListenersプロパティのコレクションにはデフォルトでDefaultTraceListenerオブジェクトが格納されているため(名前は"Default")、これを取得し、LogFileNameプロパティを設定してあげれば、ログが書き込まれるようになります。

次の例では、この方法により、"C:\test\1.txt"ファイルに書き込むようにしています。ちなみに、ファイルには追加書込みされます。

VB.NET
コードを隠すコードを選択
'Imports System.Diagnostics
'がソースファイルの一番上に書かれているものとする

'DefaultTraceListenerオブジェクトを取得
Dim drl As DefaultTraceListener
drl = CType(Trace.Listeners("Default"), DefaultTraceListener)
'LogFileNameを変更する
drl.LogFileName = "C:\test\1.txt"
C#
コードを隠すコードを選択
//using System.Diagnostics;
//がソースファイルの一番上に書かれているものとする

//DefaultTraceListenerオブジェクトを取得
DefaultTraceListener drl;
drl = (DefaultTraceListener) Trace.Listeners["Default"];
//LogFileNameを変更する
drl.LogFileName = "C:\\test\\1.txt";

Debugクラスについて

Trace.Listenersプロパティが返すリスナのコレクションは、Debug.Listenersプロパティが返すリスナのコレクションと共通です。よってTrace.Listenersプロパティに加えた変更は、Debugクラスにも適用されます。例えば上記のコードを実行すると、Trace.Writeだけでなく、Debug.Writeでもファイルに書き込まれるようになります。

トレースリスナをコレクションに追加する方法

正攻法としては、Trace.ListenersプロパティのコレクションにTextWriterTraceListenerオブジェクトを追加することで、ファイルに書き込むことができます。

先ほどのDefaultTraceListenerは、AssertUiEnabledプロパティがTrueならば、Trace.AssertTrace.Failメソッドが呼び出された時にメッセージボックスを表示しますが、TextWriterTraceListenerは表示しません。

次の例では、出力先ファイルを"C:\test\1.txt"としたTextWriterTraceListenerオブジェクトを作成し、Trace.Listenersに追加しています。

VB.NET
コードを隠すコードを選択
'Imports System.Diagnostics
'がソースファイルの一番上に書かれているものとする

'DefaultTraceListenerが必要なければ削除する
Trace.Listeners.Remove("Default")

'出力先ファイルを C:\test\1.txt、名前を LogFile として
'TextWriterTraceListenerオブジェクトを作成
Dim twtl As New TextWriterTraceListener("C:\test\1.txt", "LogFile")
'リスナコレクションに追加する
Trace.Listeners.Add(twtl)
C#
コードを隠すコードを選択
//using System.Diagnostics;
//がソースファイルの一番上に書かれているものとする

//DefaultTraceListenerが必要なければ削除する
Trace.Listeners.Remove("Default");

//出力先ファイルを C:\test\1.txt、名前を LogFile として
//TextWriterTraceListenerオブジェクトを作成
TextWriterTraceListener twtl =
    new TextWriterTraceListener("C:\\test\\1.txt", "LogFile");
//リスナコレクションに追加する
Trace.Listeners.Add(twtl);

Trace.AutoFlushプロパティがFalseの時、実際にファイルに書込みが行われるのは、CloseやFlashメソッドを呼び出した時となります。Trace.AutoFlushをTrueにすることなく自動的にフラッシュされるようにするには、次のようにAutoFlushプロパティをTrueにしたTextWriterオブジェクトを使います。

VB.NET
コードを隠すコードを選択
'Imports System.Diagnostics
'Imports System.IO
'がソースファイルの一番上に書かれているものとする

'出力ファイルを指定して、StreamWriterオブジェクトを作成
Dim sw As New StreamWriter("C:\test\1.txt")
'自動的にフラッシュされるようにする
sw.AutoFlush = True
'スレッドセーフラッパを作成
Dim tw As TextWriter = TextWriter.Synchronized(sw)
'名前を LogFile としてTextWriterTraceListenerオブジェクトを作成
Dim twtl As New TextWriterTraceListener(tw, "LogFile")
'リスナコレクションに追加する
Trace.Listeners.Add(twtl)
C#
コードを隠すコードを選択
//using System.Diagnostics;
//using System.IO;
//がソースファイルの一番上に書かれているものとする

//出力ファイルを指定して、StreamWriterオブジェクトを作成
StreamWriter sw = new StreamWriter("C:\\test\\1.txt");
//自動的にフラッシュされるようにする
sw.AutoFlush = true;
//スレッドセーフラッパを作成
TextWriter tw = TextWriter.Synchronized(sw);
//名前を LogFile としてTextWriterTraceListenerオブジェクトを作成
TextWriterTraceListener twtl =
    new TextWriterTraceListener(tw, "LogFile");
//リスナコレクションに追加する
Trace.Listeners.Add(twtl);

アプリケーション構成ファイルを使ってトレースリスナをコレクションに追加する方法

トレースのリスナコレクションにリスナを追加、削除する方法は上記のようにコードによる方法以外に、アプリケーション構成ファイルを使った方法もあります。(アプリケーション構成ファイルについては、こちらをご覧ください。)

アプリケーション構成ファイルを次のように書くことにより、出力先ファイル"C:\test\1.txt"、名前"LogFile"のTextWriterTraceListenerがトレースのリスナコレクションに追加され、DefaultTraceListenerが削除されます。ここではTraceのAutoFlushをTrueとし、インデントするスペースを4としています。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <trace autoflush="true" indentsize="4">
            <listeners>
                <add name="LogFile"
                    type="System.Diagnostics.TextWriterTraceListener"
                    initializeData="C:\test\1.txt" />
                <remove name="Default"/>
            </listeners>
        </trace>
    </system.diagnostics>
</configuration>
補足:.NET Framework 2.0からは、<sharedListeners>要素を使ってリスナの設定を記述することもできます。複数のTraceが同じリスナを使う場合に便利です。これを使った例は、こちらで紹介します。

アプリケーション構成ファイルにより、Trace.AssertやFailメソッドでメッセージボックスを表示せずにログファイルに書き込むように設定することもできます。アプリケーション構成ファイルを次のように書くことにより、Trace.AssertやFailメソッドでメッセージボックスを表示せずに、"C:\test\1.txt"に出力されるようになります。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <assert assertuienabled="false" logfilename="C:\test\1.txt"/>
    </system.diagnostics>
</configuration>

コンソールアプリケーションで、Trace.Writeでコンソールにメッセージが出力されるようにする

コンソールアプリケーションにおいて、Trace.Writeでコンソールにメッセージを出力できるようにするには、次のようにConsoleTraceListenerクラスを使用します。

VB.NET
コードを隠すコードを選択
'Imports System.Diagnostics
'がソースファイルの一番上に書かれているものとする

'コンソールに出力されるようにする
Dim ctl As New ConsoleTraceListener()
'Trace.Listenersに追加する
Trace.Listeners.Add(ctl)
C#
コードを隠すコードを選択
//using System.Diagnostics;
//がソースファイルの一番上に書かれているものとする

//コンソールに出力されるようにする
ConsoleTraceListener ctl = new ConsoleTraceListener();
//Trace.Listenersに追加する
Trace.Listeners.Add(ctl);

.NET Framework 1.1以前ではConsoleTraceListenerが使えませんが、以下のようにTextWriterTraceListenerとConsole.Outプロパティを使うことで可能です。

VB.NET
コードを隠すコードを選択
'Imports System.Diagnostics
'がソースファイルの一番上に書かれているものとする

'コンソールの出力ストリームからTextWriterTraceListenerを作成
Dim twtl As New TextWriterTraceListener(System.Console.Out)
'Trace.Listenersに追加する
Trace.Listeners.Add(twtl)
C#
コードを隠すコードを選択
//using System.Diagnostics;
//がソースファイルの一番上に書かれているものとする

//コンソールの出力ストリームからTextWriterTraceListenerを作成
TextWriterTraceListener twtl =
    new TextWriterTraceListener(System.Console.Out);
//Trace.Listenersに追加する
Trace.Listeners.Add(twtl);

その他のトレースのリスナ

なお、トレースのリスナとして.NET Frameworkで用意されているクラスには上記で説明したDefaultTraceListener、TextWriterTraceListenerの他にも様々あります。以下にトレースのリスナとして使えるクラスを紹介します。

クラス名 説明
DefaultTraceListener 通常、WriteメソッドでVisual Studioの出力ウィンドウに出力される。また、既定では、Failメソッドでメッセージボックスを表示する。
TextWriterTraceListener テキストライタやストリームに出力する。
EventLogTraceListener イベントログに出力する。
FileLogTraceListener テキストファイルに出力する。Microsoft.VisualBasic.Logging名前空間にある。.NET Framework 2.0から追加。
ConsoleTraceListener コンソールに出力する。.NET Framework 2.0から追加。
DelimitedListTraceListener 指定した区切り記号を使用する、区切られたテキスト形式のテキストライタやストリームに出力する。.NET Framework 2.0から追加。
XmlWriterTraceListener XMLエンコードされたテキストライタやストリームに出力する。.NET Framework 2.0から追加。
WebPageTraceListener ASP.NET Webページに出力する。System.Web名前空間にある。.NET Framework 2.0から追加。
補足:DefaultTraceListener.Writeメソッドは、Debugger.IsLoggingメソッドがTrueを返すならDebugger.Logメソッドを呼び出し、Falseを返すならOutputDebugString関数を呼び出します。また、Debugger.LogメソッドはOutputDebugString関数を呼び出します。OutputDebugString関数で送信されたメッセージは通常Visual Studioの出力ウィンドウに表示されますが、DebugViewのようなツールを使っても表示することができます。

EventLogTraceListenerを使った例を示します。次のコードでは、Trace.Writeでイベントログにメッセージが出力されるようにしています。

VB.NET
コードを隠すコードを選択
'Imports System.Diagnostics
'がソースファイルの一番上に書かれているものとする

'イベントログソース名を"MySouce"として出力するようにする
Dim eltl As New EventLogTraceListener("MySource")
'Trace.Listenersに追加する
Trace.Listeners.Add(eltl)
C#
コードを隠すコードを選択
//using System.Diagnostics;
//がソースファイルの一番上に書かれているものとする

//イベントログソース名を"MySouce"として出力するようにする
EventLogTraceListener eltl = new EventLogTraceListener("MySource");
//Trace.Listenersに追加する
Trace.Listeners.Add(eltl);

.NET Framework 2.0で使用できるリスナをアプリケーション構成ファイルによりTraceに追加する例を示します。アプリケーション構成ファイルを以下のようにして、listeners要素内の使用したいリスナのコメントアウトを元に戻すだけです。ログを書き込む位置などは適当に書き換えてください。(こちらを参考にして作成しました。)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <!-- <add name="EventLog" /> -->
        <!-- <add name="TextLog" /> -->
        <!-- <add name="Delimited" /> -->
        <!-- <add name="XmlWriter" /> -->
        <!-- <add name="Console" /> -->
        <!-- <add name="FileLog" /> -->
      </listeners>
    </trace>
    <sharedListeners>
      <add name="EventLog"
        type="System.Diagnostics.EventLogTraceListener"
        initializeData="sample application" />
      <add name="TextLog"
        type="System.Diagnostics.TextWriterTraceListener"
        initializeData="C:\test\TextLog.txt" />
      <add name="Delimited" 
        type="System.Diagnostics.DelimitedListTraceListener"
        initializeData="C:\test\DelimitedLog.txt"
        delimiter=","
        traceOutputOptions="DateTime" />
      <add name="XmlWriter"
        type="System.Diagnostics.XmlWriterTraceListener"
        initializeData="C:\test\Log.xml" />
      <add name="Console"
        type="System.Diagnostics.ConsoleTraceListener"
        initializeData="true" />
      <add name="FileLog"
        type="Microsoft.VisualBasic.Logging.FileLogTraceListener"
        initializeData="FileLogWriter" />
    </sharedListeners>
  </system.diagnostics>
</configuration>
  • 履歴:
  • 2007/2/7 リスナの表を追加。
  • 2007/2/8 .NET Framework 2.0で使用できるリスナをアプリケーション構成ファイルに記述する例を追加。
  • 2013/12/16 Debugクラスに関する記述を追加、ConsoleTraceListenerの具体例の追加、DefaultTraceListenerに関する補足の追加など。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。