Как написать в окне вывода Visual Studio в Мой пользовательский инструмент?

Я пишу настраиваемый инструмент, и в настоящее время я делаю то, что хочу, насколько это возможно. Я хотел бы иметь возможность писать в Visual Studio, если что-то пойдет не так. (Некорректно отформатированный код или что-то еще).

Существуют ли какие-либо стандарты для этого? Сейчас я в основном могу заставить инструмент потерпеть неудачу, а Visual Studio предупреждает, что это так. Я хотел бы получить категорию в окне вывода с любыми результирующими сообщениями, которые я хочу отправить. Я также мог бы жить с более описательной задачей/предупреждением в окне списка ошибок.

Ответ 1

Окно вывода

Чтобы записать в окно вывода "Общие" в Visual Studio, вам необходимо сделать следующее:

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

Guid generalPaneGuid = VSConstants.GUID_OutWindowGeneralPane; // P.S. There 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

Подробная информация о IVsOutputWindow и IVsOutputWindowPane можно найти в MSDN.

Список ошибок

Для добавления элементов в список ошибок, IVsSingleFileGenerator имеет вызов метода void Generate(...), который имеет параметр типа IVsGeneratorProgress. Этот интерфейс имеет метод void GeneratorError(), который позволяет сообщать об ошибках и предупреждениях в список ошибок 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);
        ...
    }
    ...
}

Подробности GeneratorError() можно найти в MSDN.

Ответ 2

Существует другой способ использования Marshal.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;
    }
}

Ответ 3

Если вы хотите, чтобы что-либо появлялось в окне вывода, оно должно поступать из stdout. Для этого ваше приложение должно быть связано как "консольное" приложение. Установите флаг /SUBSYSTEM: CONSOLE на странице свойств проекта, в Linker/System установите для свойства SubSystem значение CONSOLE.

Как только у вас появится вывод в окне, если вы включите текст "Ошибка:", он появится как ошибка или если вы установите "Предупреждение:", оно появится как предупреждение. Если текст ошибки начинается с пути/имени файла, за которым следует номер строки в скобках, среда IDE распознает его как "кликабельную" ошибку и автоматически перемещается по линии сбоев.

Ответ 5

использовать System.Diagnostics.Debugger.Message