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

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

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


person Jeff Martin    schedule 07.07.2009    source источник
comment
Почему у вас не работает запись на стандартный вывод?   -  person avakar    schedule 07.07.2009
comment
написание сообщения в Console.Write не дает мне ничего в окне вывода.   -  person Jeff Martin    schedule 08.07.2009


Ответы (5)


Окно вывода

Чтобы писать в окно вывода «Общие» в 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

Подробная информация о 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.

person Alex    schedule 05.12.2009
comment
Для настраиваемого окна: если я (VS2010) использую ваше решение, я получаю красивую оконную панель, на которой ничего не отображается. Если я изменю его на outWindow.CreatePane (ref customGuid, customTitle, 1, 0); все в порядке ... Это изменение означает, что окно не очищается после закрытия решения, и я не понимаю, почему это необходимо, чтобы окно вообще что-либо отображало. Не могли бы вы? - person BennyBarns; 30.09.2013
comment
Извините, я понятия не имею. Я написал эту вещь для VS2008, и с тех пор я особо не занимался разработкой плагинов VS ... - person Alex; 30.09.2013
comment
В моем случае панель не активируется. customPane.Activate(); не работает. любая идея? - person Rashmin Javiya; 27.09.2017

Есть еще один способ использовать 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;
    }
}
person Ian Davis    schedule 10.06.2012
comment
Принятый ответ не работает для меня в VS2010, тогда как это работает - person smirkingman; 23.05.2014
comment
Хотя это работает, если у вас открыто несколько экземпляров Visual Studio, сообщение, вероятно, попадет в первый, который вы открыли. - person Emond Erno; 05.06.2014

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

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

person John Deters    schedule 07.07.2009
comment
Я делаю это на C #, и в свойстве проекта нет / подсистемы, нужно ли мне создавать консольное приложение для этого? он работает сейчас как DLL, но, очевидно, я не получаю вывода. - person Jeff Martin; 08.07.2009
comment
Это DLL? Как это вызывается? Обычно окно вывода захватывает инструменты, которые выполняются в цепочке инструментов, которую создает MSBuild, но, насколько я знал, все они были независимыми исполняемыми файлами, и MSBuild просто фиксировал весь стандартный вывод для отображения в окне. Мне только что пришло в голову, что ваш настраиваемый инструмент может не иметь отношения к строительству. Окно вывода зарезервировано для процесса сборки. Если вы хотите вывести информацию о времени выполнения, вам следует использовать окно отладки (с OutputDebugString () или Debug.Print () или чем-то еще.) - person John Deters; 08.07.2009
comment
Спасибо, Джон. Я обнаружил, как создать ошибку в MSBuild благодаря удаче, и искал в Интернете, как создать предупреждение. Интересно, что ваше описание не работало непосредственно на меня. Я заставил его работать, выведя: warning: ‹text› (без кавычек). Visual Studio требовалось начальное двоеточие, которое используется для отделения информации о файле / строке № от текста предупреждения, если предупреждение связано с конкретным файлом / строкой №. По какой-то причине VS 2008 не принимает только предупреждение: текст. Кроме того, не имело значения, был ли выходной поток stdout, stderr и т. Д. И он чувствителен к регистру. Боже. - person David Gladfelter; 22.12.2010

Вы можете использовать классы Debug и / или Trace. Здесь есть некоторая информация: http://msdn.microsoft.com/en-us/library/bs4c1wda(VS.71).aspx

Удачи.

person Jon Onstott    schedule 07.07.2009
comment
Я пробовал trace.write (сообщение, категория), прежде чем спрашивать об этом, и он не выводился. - person Jeff Martin; 08.07.2009

используйте 1_

person David Egli    schedule 09.04.2012