2010-12-13 12 views
27

.NET Framework 4で使用すると、SysInternalsのDebugViewは機能しなくなりました。いくつかの調査によれば、フレームワークの新しいアーキテクチャでは、デバッガが接続されていればトレースをキャプチャできませんでした。私の場合はVisual Studioデバッガです。ターゲットフレームワークを4から3.5に変更すると、再び機能します。DebugViewを.NET 4で動作させるには?

Visual Studioデバッガを接続した状態で、DebugViewを.NET 4で動作させる方法は誰も知っていますか? TraceクラスのListenersコレクションをクリアしようとしましたが、運はありませんでした。

+2

実際には本当です。ただし、Visual Studioの* Output *ウィンドウにトレースメッセージが表示されます。 –

+3

問題はMSに報告されました:https://connect.microsoft.com/VisualStudio/feedback/details/457063/outputdebugstring-doesnt-work-in-the-debugger-vs-2010-pro-beta-1-c? wa = wsignin1.0#そして彼らの答えはこれが「デザイン」であるということでした。回避策が存在する場合、私はそれを知りたいです。 。 。 –

+0

私はVisual Studioの出力を使用できることを知っています。しかし、DebugViewほど役に立ちません。フィルタリングはしていませんが、スクロールし続けるだけです...私はDebugViewのような素晴らしいツールとして、驚いています。回避策がないようです。 –

答えて

23

.NETトレースメッセージは、WindowsカーネルのOutputDebugString関数を使用して生成されます。 MSDNに記載されているこの関数は、

を表示するためにデバッガに文字列を送信します。

明らかに、ネイティブデバッガはこのメッセージを受け取ります。これは、この動作が仕様であることをremarkが意味します。 .NET 4.0より前のDebugViewなどの他のリスナーにメッセージが渡された理由は、Visual Studioが.NETコードを「ネイティブ」デバッガとしてデバッグしなかったためです。デバッグビューは、ネイティブデバッガが接続されている場合には動作しませんでした。

デバッガが接続されていない別のプロセスにすべてのメッセージを転送するTraceListenerを追加することで回避できます。通信は、任意のIPCメカニズムを使用して実現することができる。以下は、TCPソケットを使用したサンプルです。


サーバーアプリケーション

これは、開始とTraceListenerクラスによって自動的に停止しますシンプルなスタンドアローンのコマンドラインプログラムのようになります。

using System; 
using System.Diagnostics; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     if (args.Length != 1) 
     { 
      Console.WriteLine("Usage: DebugOutputListener.exe <port>"); 
      return; 
     } 
     TcpListener server = null; 
     try 
     { 
      Int32 port = Convert.ToInt32(args[0]); 
      IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 

      server = new TcpListener(localAddr, port); 
      server.Start(); 

      while (true) 
      { 
       Console.Write("Waiting for a connection... "); 

       using (TcpClient client = server.AcceptTcpClient()) 
       { 
        using (NetworkStream stream = client.GetStream()) 
        { 

         byte[] bufferLength = new byte[4]; 
         stream.Read(bufferLength, 0, 4); 
         int length = BitConverter.ToInt32(bufferLength, 0); 

         if (length == -1) 
         { 
          // close message received 
          Trace.WriteLine("DebugOutputListener is closing."); 
          return; 
         } 

         byte[] bufferMessage = new byte[length]; 
         stream.Read(bufferMessage, 0, length); 

         string msg = Encoding.UTF8.GetString(bufferMessage); 
         Trace.WriteLine(msg); 
        } 
       } 
      } 
     } 
     catch (SocketException e) 
     { 
      Console.WriteLine("SocketException: {0}", e); 
     } 
     finally 
     { 
      server.Stop(); 
     } 
    } 
} 

のTraceListener

あなたのニーズに応じて
using System; 
using System.Diagnostics; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 

public class DebugOutputTraceListener : TraceListener 
{ 
    private IPEndPoint ipEndPoint; 
    private bool needsDisposing; 

    public DebugOutputTraceListener(string debugOutputListenerPath, int port) 
    { 
     this.ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13000); 

     // start the process that forwards the trace messages 
     var psi = new ProcessStartInfo() 
     { 
      FileName = debugOutputListenerPath, 
      Arguments = port.ToString(), 
      CreateNoWindow = true, 
      UseShellExecute = false 
     }; 
     Process.Start(psi); 
     needsDisposing = true; 
    } 

    ~DebugOutputTraceListener() 
    { 
     Dispose(false); 
    } 

    public override void Write(string message) 
    { 
     sendMessage(message); 
    } 

    public override void WriteLine(string message) 
    { 
     sendMessage(message + Environment.NewLine); 
    } 

    private void sendMessage(string message) 
    { 
     try 
     { 
      using (TcpClient client = new TcpClient()) 
      { 
       client.Connect(ipEndPoint); 
       byte[] bufferMessage = Encoding.UTF8.GetBytes(message); 
       byte[] bufferLength = 
        BitConverter.GetBytes(bufferMessage.Length); 

       using (NetworkStream stream = client.GetStream()) 
       { 
        stream.Write(bufferLength, 0, bufferLength.Length); 
        stream.Write(bufferMessage, 0, bufferMessage.Length); 
       } 
      } 
     } 
     catch (SocketException e) 
     { 
      Trace.WriteLine(e.ToString()); 
     } 
    } 

    /// <summary> 
    /// Sends -1 to close the TCP listener server. 
    /// </summary> 
    private void sendCloseMessage() 
    { 
     try 
     { 
      using (TcpClient client = new TcpClient()) 
      { 
       client.Connect(ipEndPoint); 
       byte[] buffer = BitConverter.GetBytes(-1); 

       using (NetworkStream stream = client.GetStream()) 
       { 
        stream.Write(buffer, 0, buffer.Length); 
       } 
      } 
     } 
     catch (SocketException e) 
     { 
      Trace.WriteLine(e.ToString()); 
     } 
    } 

    public override void Close() 
    { 
     sendCloseMessage(); 
     needsDisposing = false; 
     base.Close(); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (needsDisposing) 
     { 
      sendCloseMessage(); 
      needsDisposing = false; 
     } 
     base.Dispose(disposing); 
    } 
} 

使用

public class Program 
{ 
    [STAThread] 
    static void Main(string[] args) 
    { 
     // using Debug; start a listener process on port 13000 
     Debug.Listeners.Add(
      new DebugOutputTraceListener("DebugOutputListener.exe", 13000)); 
     Debug.WriteLine("A debug message."); 

     // using Trace; start a listener process on port 13001 
     Trace.Listeners.Add(
      new DebugOutputTraceListener("DebugOutputListener.exe", 13001)); 
     Trace.WriteLine("A trace message"); 
    } 
} 
+0

ありがとうございます。大きな説明と回避策。 –

+0

これはクールです。私はそれを2回upvoteすることを望みます。私はあなたがデバッガで実行されておらず、DbgViewを実行していない場合、これをすべてスキップする小さな最適化を行いました。初期化コードを次のように囲みます:if(Debugger.IsAttached && Process.GetProcessesByName( "Dbgview")。Any()) –

17

、単純な回避策があります:ちょうどCtrlキーを押しながらF5を使用して、デバッガなしにアプリを起動します。

私はDebugViewを使用して、デバッガで動作しないホストされたSilverlightアプリケーションからデバッグステートメントを取得したいと考えていました。これは.NET 4より前のように動作しませんが、デバッグなしでホストを起動すると、デバッガのステートメントが実行され、DebugViewに表示されます。

+1

ありがとう!これが最も簡単な回避策です。 – duyn9uyen

6

これは私のために問題を修正しました:私は、.NET 4.5から.NET 4にいくつかのプロジェクトをダウングレードするとき

Trace.Autoflush = true; 
+0

大文字小文字の区別:Trace.AutoFlush = true; –

2

は、私はこの問題に遭遇した - 突然すべての私のデバッグビューのデータが消えて(と私は直接PInvokingましたto :: OutputDebugString)。とにかく、デバッグビュー(4.81)の最新の最新バージョンにアップグレードすることで問題は解決しました。

関連する問題