1

我已经阅读了几篇文章,这些文章告诉您如何从附加组件(特别是 Visual Studio 2008 集成包,通过 Visual Studio 2008 SDK 1.1)中将文本添加到 Visual Studio 中的输出窗口,但没有示例说明如何从输出窗口读取文本。我的目标是在调试某个应用程序(TRACE 输出和可能的标准输入/标准输出)时从调试输出窗口解析文本。IVsOutputWindowPane 接口没有从输出窗口读取文本的方法。该文档似乎暗示这是可能的,但它没有提供示例:

http://msdn.microsoft.com/en-us/library/bb166236(VS.80).aspx

Quote: 此外,OutputWindow 和OutputWindowPane 对象添加了一些更高级别的功能,使枚举输出窗口窗格和从窗格中检索文本更容易。

最好我希望能够订阅一个在新文本行到达时触发的事件,类似于 StreamReader 的异步读取。

4

4 回答 4

4

有可能,这只是一条漫长的曲折之路:

ServiceProvider -> IVsOutputWindow -> GetPane( debugwindow ) -> IVsUserData -> GetData( wpftextviewhost ) -> IWpfTextViewHost -> IWpfTextView -> TextBuffer -> 已更改事件。

假设你有一个IServiceProvider来自其他地方的 VS(vsix 扩展/不管,全球服务提供商),并且没有任何错误检查,它看起来像这样:

IVsOutputWindow outWindow = ServiceProvider.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow;
Guid debugPaneGuid = VSConstants.GUID_OutWindowDebugPane;
IVsOutputWindowPane pane;
outWindow.GetPane(ref debugPaneGuid, out pane);
// from here up you'll find in lots of other stackoverflow answers, 

// the stuff from here down is interesting to this question
IVsUserData userData = (IVsUserData)pane;
object o;
Guid guidViewHost = DefGuidList.guidIWpfTextViewHost;
userData.GetData(ref guidViewHost, out o);

IWpfTextViewHost viewHost = (IWpfTextViewHost)o;
IWpfTextView textView = viewHost.TextView;
textView.TextBuffer.Changed += YourTextChangedHandlerHere;

每次输出窗口获取更多数据时,都会调用您的文本更改处理程序。你不一定会一行一行地得到它,但你可能更有可能得到你需要自己处理的大块。

在 2010 年的 VS 中,很可能以上某些内容甚至不存在。但现在存在!

于 2014-04-02T01:02:20.033 回答
1

VS 的默认行为(当您没有明确设置侦听器时)是在调试器输出窗口中显示跟踪消息,如果您想要一个简单的解决方案并且不对消息执行其他操作,您会很感激。

不幸的是,这不是你的情况。因此,您必须定义一个跟踪侦听器来发送(和存储)您的跟踪消息,然后您就可以在其中读取它们。跟踪侦听器可以是一个文件(例如 XML),或者如果您不想为附加文件而烦恼,您可以通过从基类 TraceListener 派生一个类来创建自定义侦听器。

于 2010-03-07T11:10:32.867 回答
1

我不知道你问的是可能的。但是,您可以将加载项注册为应用程序的调试器,以便获得跟踪消息的输出。这些通常被路由到 OutputDebugString,并且可以按照本文所述进行捕获:http ://www.drdobbs.com/showArticle.jhtml?articleID=184410719 。它不会给你正常的输出,只是调试,但它不依赖于被调试应用程序的技术。

于 2010-03-07T13:55:52.450 回答
0

此页面上的解决方案选择文本以便阅读。我希望有更好的方法。 首次编译错误时自动停止 Visual C++ 2008 构建?

Private Sub OutputWindowEvents_OnPaneUpdated(ByVal pPane As OutputWindowPane) Handles OutputWindowEvents.PaneUpdated
    pPane.TextDocument.Selection.SelectAll()
    Dim Context As String = pPane.TextDocument.Selection.Text
    pPane.TextDocument.Selection.EndOfDocument()
End Sub
于 2010-03-25T05:09:34.663 回答