2009-07-07 2 views
27

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

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

+0

Почему вы не работаете на стандартном выходе? – avakar

+0

написать сообщение Console.Write не дает мне ничего в окне вывода. –

ответ

44

Окно вывода

Для записи в окне вывода «Общие» в 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.

+0

Для пользовательского окна: если I (VS2010) использует ваше решение, я получаю красивое окно, которое ничего не отображает. Если я изменю его на outWindow.CreatePane (ref customGuid, customTitle, 1, 0); все хорошо ... Это изменение означает, что окно не очищается после закрытия решения, и я не понимаю, почему это необходимо, чтобы окно отображало что-либо вообще. Ты можешь? – BennyBarns

+0

Извините, я понятия не имею. Я написал эту вещь для VS2008, и с тех пор я не занимался разработкой плагина VS ... – Alex

+0

В моем случае панель не активируется. 'customPane.Activate();' не работает. Есть идеи? –

0

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

Удачи.

+1

Я попробовал trace.write (сообщение, категория), прежде чем спрашивать об этом, и он не выводил. –

4

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

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

+0

Я делаю это в C#, и в свойстве проекта нет/подсистемы, мне нужно сделать консольное приложение для этого? его работа прямо сейчас как DLL, но, очевидно, я не получаю выход. –

+0

Это DLL? Как вызывается? Обычно окно вывода захватывает инструменты, которые выполняются в цепочке инструментов, которые строятся MSBuild, но насколько я знал, все они были независимыми исполняемыми файлами, а MSBuild просто захватывал все stdout для отображения в окне. Мне пришло в голову, что ваш собственный инструмент не может быть связан со строительством. Окно «Выход» зарезервировано для процесса сборки. Если вы хотите опубликовать информацию о времени выполнения, вы должны использовать окно отладки (с OutputDebugString() или Debug.Print() или что-то еще.) –

+2

Спасибо, Джон. Я обнаружил, как создать ошибку в MSBuild через удачу и искал в Интернете, как создать предупреждение. Интересно, что ваше описание не работало напрямую для меня. Я получил его для работы, выведя «: warning: » (без кавычек). Visual studio хотел, чтобы ведущий двоеточие, который используется для разделения информации о файле/строке # из текста предупреждения, если предупреждение связано с конкретным файлом/строкой #. По какой-то причине VS 2008 не будет принимать только «предупреждение: текст». Кроме того, неважно, был ли выходной поток stdout, stderr и т. Д. И он учитывает регистр. Geesh. –

-2

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

7

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

Принятый ответ для меня не работает в VS2010, тогда как это делает – smirkingman

+2

Хотя это работает, если у вас есть несколько экземпляров Visual Studio, сообщение, вероятно, окажется в первом открывшемся. –

Смежные вопросы