Visual studio 如何在自定义工具中写入Visual Studio输出窗口?

Visual studio 如何在自定义工具中写入Visual Studio输出窗口?,visual-studio,vsx,customtool,Visual Studio,Vsx,Customtool,我正在编写一个自定义工具,目前我已经让它尽可能实现我想要的功能。如果出现问题,我希望能够写信给VisualStudio。(格式不正确的代码或其他内容) 这有什么标准吗?现在我基本上可以强制工具失败,VisualStudio会发出警告,说明它已经失败了。我希望在输出窗口中有一个类别,其中包含我想要发送的任何结果消息。我还可以在错误列表窗口中看到更具描述性的任务/警告。您可以使用调试和/或跟踪类。这里有一些信息: 祝你好运。如果你想在输出窗口中显示任何东西,它必须来自标准输出。为此,您的应用程序需

我正在编写一个自定义工具,目前我已经让它尽可能实现我想要的功能。如果出现问题,我希望能够写信给VisualStudio。(格式不正确的代码或其他内容)


这有什么标准吗?现在我基本上可以强制工具失败,VisualStudio会发出警告,说明它已经失败了。我希望在输出窗口中有一个类别,其中包含我想要发送的任何结果消息。我还可以在错误列表窗口中看到更具描述性的任务/警告。

您可以使用调试和/或跟踪类。这里有一些信息:


祝你好运。

如果你想在输出窗口中显示任何东西,它必须来自标准输出。为此,您的应用程序需要链接为“控制台”应用程序。在项目的属性页中,在Linker/System下设置/SUBSYSTEM:CONSOLE标志,将SUBSYSTEM属性设置为CONSOLE

在窗口中显示输出后,如果包含文本“Error:”将显示为错误,或者如果设置了“Warning:”将显示为警告。如果错误文本以路径/文件名开头,后跟括号中的行号,IDE会将其识别为“可单击”错误,并自动导航到错误行。

输出窗口 要写入Visual Studio中的“常规”输出窗口,需要执行以下操作:

IVsOutputWindow outWindow = Package.GetGlobalService( typeof( SVsOutputWindow ) ) as IVsOutputWindow;

Guid generalPaneGuid = VSConstants.GUID_OutWindowGeneralPane; // P.S. There's also the GUID_OutWindowDebugPane available.
IVsOutputWindowPane generalPane;
outWindow.GetPane( ref generalPaneGuid , out generalPane );

generalPane.OutputString( "Hello World!" );
generalPane.Activate(); // Brings this pane into view
但是,如果要写入自定义窗口,则需要执行以下操作:

IVsOutputWindow outWindow = Package.GetGlobalService( typeof( SVsOutputWindow ) ) as IVsOutputWindow;

// Use e.g. Tools -> Create GUID to make a stable, but unique GUID for your pane.
// Also, in a real project, this should probably be a static constant, and not a local variable
Guid customGuid = new Guid("0F44E2D1-F5FA-4d2d-AB30-22BE8ECD9789");
string customTitle = "Custom Window Title";
outWindow.CreatePane( ref customGuid, customTitle, 1, 1 );

IVsOutputWindowPane customPane;
outWindow.GetPane( ref customGuid, out customPane);

customPane.OutputString( "Hello, Custom World!" );
customPane.Activate(); // Brings this pane into view
有关和的详细信息可在MSDN上找到

错误列表 要将项目添加到错误列表中,
IVsSingleFileGenerator
有一个方法调用
void Generate(…)
,该方法调用的参数类型为
IVsGeneratorProgress
。此接口有一个方法
void generator error()
,用于向Visual Studio错误列表报告错误和警告

public class MyCodeGenerator : IVsSingleFileGenerator
{
    ...
    public void Generate( string inputFilePath, string inputFileContents, string defaultNamespace, out IntPtr outputFileContents, out int output, IVsGeneratorProgress generateProgress )
    {
        ...
        generateProgress.GeneratorError( false, 0, "An error occured", 2, 4);
        ...
    }
    ...
}

可以在MSDN上找到的详细信息。

使用
系统.诊断.调试器.消息
还有另一种方法可以使用
封送.GetActiveObject
获取正在运行的
DTE2
实例

第一个参考EnvDTE和envdte80。这项功能目前在VisualStudio 2012中有效,但我还没有尝试其他功能

using System;
using System.Runtime.InteropServices;
using EnvDTE;
using EnvDTE80;

internal class VsOutputLogger
{
    private static Lazy<Action<string>> _Logger = new Lazy<Action<string>>( () => GetWindow().OutputString );

    private static Action<string> Logger
    {
        get { return _Logger.Value; }
    }

    public static void SetLogger( Action<string> logger )
    {
        _Logger = new Lazy<Action<string>>( () => logger );
    }

    public static void Write( string format, params object[] args)
    {
        var message = string.Format( format, args );
        Write( message );
    }

    public static void Write( string message )
    {
        Logger( message + Environment.NewLine );
    }

    private static OutputWindowPane GetWindow()
    {
        var dte = (DTE2) Marshal.GetActiveObject( "VisualStudio.DTE" );
        return dte.ToolWindows.OutputWindow.ActivePane;
    }
}
使用系统;
使用System.Runtime.InteropServices;
使用EnvDTE;
使用EnvDTE80;
内部类VsOutputLogger
{
私有静态惰性记录器=新惰性(()=>GetWindow().OutputString);
专用静态动作记录器
{
获取{return\u Logger.Value;}
}
公共静态无效设置记录器(操作记录器)
{
_记录器=新的延迟(()=>记录器);
}
公共静态无效写入(字符串格式,参数对象[]args)
{
var message=string.Format(格式,args);
写(信息);
}
公共静态无效写入(字符串消息)
{
记录器(message+Environment.NewLine);
}
私有静态输出窗格GetWindow()
{
var dte=(DTE2)Marshal.GetActiveObject(“VisualStudio.dte”);
返回dte.ToolWindows.OutputWindow.ActivePane;
}
}

为什么写入标准输出对您不起作用?向控制台写入消息。写入在输出窗口中没有给出任何信息。在询问此问题之前,我尝试了trace.Write(消息,类别),但它没有输出。我在C#中执行此操作,并且项目属性中没有/subsystem内容,是否需要制作控制台应用程序来执行此操作?它现在作为一个DLL工作,但显然我没有得到输出。它是一个DLL?它是如何被调用的?通常,输出窗口捕获在MSBuild构造的工具链中执行的工具,但据我所知,这些工具都是独立的可执行文件,而MSBuild只捕获所有stdout以在窗口中显示。我刚刚想到,您的自定义工具可能与构建无关。“输出”窗口是为构建过程保留的。如果您希望输出运行时信息,那么应该使用调试窗口(带有OutputDebugString()或debug.Print()或其他任何内容)。谢谢,John。幸运的是,我发现了如何在MSBuild中创建错误,并在web上搜索如何创建警告。有趣的是,你的描述对我并不直接有效。我通过输出“:warning:”(不带引号)让它工作。Visual studio需要前导冒号,如果警告与特定文件/行关联,则该冒号用于将文件/行信息与警告文本分开。由于某些原因,VS2008不会只接受“警告:文本”。另外,输出流是否为stdout、stderr等也无关紧要,而且它是区分大小写的。Geesh.对于自定义窗口:如果我(VS2010)使用你的解决方案,我会得到一个很好的窗格,它什么也不显示。如果我将其更改为outhindow.CreatePane(参考customGuid,customTitle,1,0);一切都很好。。。这个更改意味着在解决方案关闭后窗口不会被清除,我不明白为什么窗口需要显示任何内容。你能吗?对不起,我不知道。我为VS2008写了这篇文章,从那时起我就没有真正处理过VS插件开发……在我的例子中,面板并没有激活<代码>自定义窗格。激活()不工作。有什么想法吗?对于我来说,接受的答案在VS2010中不起作用,而这不起作用。尽管这样做有效,但如果您打开了多个Visual Studio实例,那么消息可能会在您打开的第一个实例中结束。