Thông báo theo dõi .NET được phát ra bằng chức năng OutputDebugString
trong nhân Windows. Chức năng này, như được ghi trong MSDN,
gửi một chuỗi tới trình gỡ rối để hiển thị.
Rõ ràng, trình gỡ lỗi gốc sẽ nhận được thông báo này. Điều này có nghĩa là bởi remark rằng hành vi này là do thiết kế. Lý do các thông điệp được truyền cho các trình lắng nghe khác như DebugView trước .NET 4.0 là Visual Studio đã không gỡ lỗi mã .NET như một trình gỡ rối "bản địa"; DebugView chưa bao giờ làm việc khi một trình gỡ lỗi gốc được đính kèm.
Cách giải quyết có thể là thêm TraceListener
chuyển tiếp tất cả thư đến một quy trình khác không đính kèm trình gỡ lỗi. Giao tiếp có thể được thực hiện bằng cách sử dụng bất kỳ cơ chế IPC nào. Sau đây là một mẫu sử dụng các cổng TCP.
Application Server
Đây sẽ là một chương trình dòng lệnh độc lập đơn giản mà được bắt đầu và dừng tự động bởi lớp 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);
}
}
Cách sử dụng
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");
}
}
Thực sự đúng.Tuy nhiên, bạn sẽ tìm thấy các thông điệp dấu vết trong cửa sổ * Output * của Visual Studio. –
Sự cố đã được báo cáo cho MS: https://connect.microsoft.com/VisualStudio/feedback/details/457063/outputdebugstring-doesnt-work-in-the-debugger-vs-2010-pro-beta-1-c? wa = wsignin1.0 # và câu trả lời của họ là đây là "Thiết kế". Nếu một workaround tồn tại tôi rất thích biết nó. . . –
Tôi biết tôi có thể sử dụng đầu ra của Visual Studio. Nhưng nó gần như không hữu ích như DebugView. Không lọc, thứ chết tiệt chỉ giữ cuộn ... Tôi ngạc nhiên, công cụ tuyệt vời như DebugView là, không có cách giải quyết nào có sẵn. –