Debug|Trace.WriteLine 来自 Visual Studio 中的 C# 插件 - 通过 ConsoleTraceListener 显示

Posted

技术标签:

【中文标题】Debug|Trace.WriteLine 来自 Visual Studio 中的 C# 插件 - 通过 ConsoleTraceListener 显示【英文标题】:Debug|Trace.WriteLine from C# plugin in Visual Studio - display via ConsoleTraceListener 【发布时间】:2014-06-29 12:19:29 【问题描述】:

我已经修改了一个 C# 插件,它是 Visual Studio 2.0 的 Python 工具的一部分,并希望在代码中查看 Debug.WriteLine 和 Trace.WriteLine 语句的输出。注意这个插件是用在Visual Studio 2013本身的,修改python进程的调试....

我希望我可以按照 pminaev on the PTVS discussion forum here 的建议在 devenv.exe.config 添加一个跟踪侦听器(将另一个 VS 附加到 VS 本身似乎很笨拙,所以我希望避免这种情况)。

我认为其他 .NET 应用程序的正确配置似乎不适用于 VS2013 本身。我的努力记录如下。

如果有人设法将插件调试/跟踪输出重定向到 Visual Studio 控制台(或其他比附加的 VS 实例更方便的地方),非常感谢提示......


我的 Google-fu 找到了几个示例,基于这些示例我尝试添加...

<system.diagnostics>
    <trace autoflush="true" />
        <listeners>
            <add name="myConsoleTraceListener" type="System.Diagnostics.ConsoleTraceListener" />
        </listeners>
    </trace>
</system.diagnostics>

...和...

<system.diagnostics>
    <source name="System.ServiceModel.MessageLogging" switchValue="Verbose, ActivityTracing">
        <listeners>
            <add name="myTraceListener" />
        </listeners>
    </source>
    <sharedListeners>
        <add name="myTraceListener" type="System.Diagnostics.ConsoleTraceListener" />
    </sharedListeners>
</system.diagnostics>

之后启动 PTVS,没有任何用处。无论使用哪种配置,我都会弹出一个窗口:

The `Python Tools Package' package id not load correctly.

The problem may have been caused by a configuration change or by
the installation of another extension.  You can get more information by
examining the file
'C:\Users\XXX\AppData\Roaming\Microsoft\VisualStudio\12.0\Acti
vityLog.xml'.

ActivityLog 对我来说意义不大:

<entry>
    <record>41</record>
    <time>2014/05/12 07:52:47.851</time>
    <type>Error</type>
    <source>VisualStudio</source>
    <description>CreateInstance failed for package [Python Tools Package]</description>
    <guid>6DBD7C1E-1F1B-496D-AC7C-C55DAE66C783</guid>
    <hr>80131604</hr>
    <errorinfo>Exception has been thrown by the target of an invocation.</errorinfo>
</entry>
<entry>
    <record>42</record>
    <time>2014/05/12 07:52:47.851</time>
    <type>Error</type>
    <source>VisualStudio</source>
    <description>End package load [Python Tools Package]</description>
    <guid>6DBD7C1E-1F1B-496D-AC7C-C55DAE66C783</guid>
    <hr>80004005 - E_FAIL</hr>
    <errorinfo>Exception has been thrown by the target of an invocation.</errorinfo>
</entry>

当我尝试附加到远程 python 进程时,我得到另一个弹出窗口:

Unable to connect to 'secret@server'.  Operation not supported.
Unknown error: 0x80131902.

Google-foo 提示这是加载 .NET 版本失败...?

【问题讨论】:

该错误似乎与 Visual Studio 或 Visual Studio 内部的跟踪无关,它似乎与 Python 工具包本身有关。要调试此故障,您可以使用另一个 VS 调试 VS 并打开所有异常(ctrl-D + E,选中“Thrown”)。 @SimonMourier:Python Tools C# 插件只调用了System.Diagnostics.Debug.WriteLineSystem.Diagnostics.Trace.WriteLine,所以我看不出这个问题是如何“与 Python 工具包本身有关”的。由于我只想在某处查看调试/跟踪,而不是单步执行代码或拦截异常,因此我不愿意附加另一个 VS 实例……这似乎不是满足我的开发需求的有效方法。 '“Python 工具包”包 ID 未正确加载。'表示 VS 检测到 this 包有问题。例如,错误可能是包括 DLL 引用问题在内的任何内容。我的调试建议只是找出this问题的原因,仅此而已。 @SimonMourier: 哦,我明白了......是的 - 我可以看到我添加到 Python 工具 DLL 中的一些文件附加的输出,所以我知道它正在加载和执行,我想我已经精神上忘记了甚至有关于加载的警告......我会回到那个,看看整理它是否让VS处理跟踪侦听器配置。真的谢谢你! @SimonMourier:所以-这些错误仅在我在 devenv.exe.config 中有附加的“最佳猜测”&lt;system.diagnostics&gt; 标记行时出现,如上面问题中列出的那样-我想问题仍然存在什么配置可以在没有错误的情况下工作...... 【参考方案1】:

我想为我写的插件做类似的事情:pMixins。我使用 log4net 而不是 System.Diagnostics,但想将日志消息路由到 Visual Studio 输出窗口。

我从来没有使用基于配置的方法来工作,最终以编程方式进行布线。此外,我必须创建一个自定义日志编写器来写入 Visual Studio 输出窗口。

在我的包文件中 (https://github.com/ppittle/pMixins/blob/master/pMixins.VSPackage/pMixinsVisualStudioCodeGenerateInitializer.cs):

protected override void Initialize()


      //Create a Visual Studio Writer
       _visualStudioWriter = new VisualStudioWriter(dte, this);

      //Initialize Logging
      Log4NetInitializer.Initialize(_visualStudioWriter, this);
 

VisualStudioWriter(摘要)(https://github.com/ppittle/pMixins/blob/master/pMixins.VSPackage/Infrastructure/VisualStudioWriter.cs):

public class VisualStudioWriter : IVisualStudioWriter
  
    private EnvDTE.OutputWindowPane _outputWindowPane;

    public VisualStudioWriter(DTE dte, System.IServiceProvider serviceProvider)
                          
        _outputWindowPane = LoadOutputWindowPane(dte);
    

    private EnvDTE.OutputWindowPane LoadOutputWindowPane(DTE dte)
    
        const string windowName = "pMixins Code Generator";
        EnvDTE.OutputWindowPane pane = null;
        EnvDTE.Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
        if (window != null)
        
            EnvDTE.OutputWindow output = window.Object as EnvDTE.OutputWindow;
            if (output != null)
            
                pane = output.ActivePane;
                if (pane == null || pane.Name != windowName)
                
                    for (int ix = output.OutputWindowPanes.Count; ix > 0; ix--)
                    
                        pane = output.OutputWindowPanes.Item(ix);
                        if (pane.Name == windowName)
                            break;
                    
                    if (pane == null || pane.Name != windowName)
                        pane = output.OutputWindowPanes.Add(windowName);
                    if (pane != null)
                        pane.Activate();
                
            
        
        return pane;
    

    public void OutputString(string s)
    
        _outputWindowPane.OutputString(s);
    
 

Log4NetInitializer(总结)https://github.com/ppittle/pMixins/blob/master/CopaceticSoftware.CodeGenerator.StarterKit/Logging/Log4NetInitializer.cs

public static class Log4NetInitializer

    public static void Initialize(IVisualStudioWriter visualStudioWriter,
                       IServiceProvider serviceProvider)
    
       //http://***.com/questions/650694/changing-the-log-level-programmaticaly-in-log4net
       var outputWindowAppender =
           new VisualStudioOutputWindowAppender(visualStudioWriter)
           
               Layout =
                       new PatternLayout(@"%dateHH:mm:ss,fff %thread% %-5level [%logger2] %message%newline"),
                    Threshold =
                    #if DEBUG
                     Level.Debug
                     #else
                    Level.Info
                        #endif
           ;


       log4net.Config.BasicConfigurator.Configure(
                outputWindowAppender);                

    

最后,VisualStudioOutputWindowAppender (https://github.com/ppittle/pMixins/blob/master/CopaceticSoftware.CodeGenerator.StarterKit/Logging/VisualStudioOutputWindowAppender.cs)

public class VisualStudioOutputWindowAppender : AppenderSkeleton

    public IVisualStudioWriter OutputWindow  get; set; 

    public VisualStudioOutputWindowAppender(IVisualStudioWriter outputWindow)
    
        OutputWindow = outputWindow;

        Layout = new PatternLayout("%-5level %logger - %message%newline");
    

    protected override void Append(LoggingEvent loggingEvent)
    
        if (null == OutputWindow)
            return;

        if (null == loggingEvent)
            return;

        OutputWindow.OutputString(RenderLoggingEvent(loggingEvent));
    

希望有帮助

【讨论】:

感谢您分享您的方法 - 听起来不错。我目前正在将跟踪/日志记录写入文本文件并在独立查看器中查看它,但这有时可能更方便......我会在有机会时尝试一下。干杯和 +1。 当它最终工作时,从 Visual Studio 输出 id 获取日志输出非常方便。但是在初始开发期间,从日志文件中提取当然就足够了。祝你好运!

以上是关于Debug|Trace.WriteLine 来自 Visual Studio 中的 C# 插件 - 通过 ConsoleTraceListener 显示的主要内容,如果未能解决你的问题,请参考以下文章

如何将 System.Diagnostics.Trace 和 System.Diagnostics.Debug 消息记录到 NLog 文件?

非控制台应用程序输出信息到输出面板

C#有没有DEBUG调试输出的语句提供输出变量值?

将时间戳添加到 Trace.WriteLine()

错误调式

web项目 在visual studio 输出窗口显示调试信息