扩展“输出”窗口

输出 ”窗口是一组读/写文本窗格。 Visual Studio 包含以下内置窗格: 生成,其中项目传达有关生成的消息,以及 Visual Studio 在生成中传达有关 IDE 的消息的常规。 项目通过IVsBuildableProjectCfg接口方法自动获取对“生成”窗格的引用,Visual Studio 通过SVsGeneralOutputWindowPane服务直接访问“常规”窗格。 除了内置窗格,还可以创建和管理自己的自定义窗格。

可以直接通过IVsOutputWindow接口IVsOutputWindowPane控制“输出”窗口。 服务 IVsOutputWindow 提供的 SVsOutputWindow 接口定义用于创建、检索和销毁 输出 窗口窗格的方法。 该 IVsOutputWindowPane 接口定义用于显示窗格、隐藏窗格和操作其文本的方法。 控制 “输出 ”窗口的另一种方法是通过 OutputWindow Visual Studio 自动化对象模型中的对象和 OutputWindowPane 对象。 这些对象几乎封装了接口的所有IVsOutputWindowPane功能IVsOutputWindow。 此外, OutputWindow 这些对象添加了 OutputWindowPane 一些更高级别的功能,以便更轻松地枚举 “输出 ”窗口窗格以及从窗格中检索文本。

创建使用“输出”窗格的扩展

可以创建一个扩展,用于练习“输出”窗格的不同方面。

  1. 创建一个名为 TestOutput 的菜单命令命名TestOutputVSIX 项目。 有关详细信息,请参阅 使用菜单命令创建扩展。

  2. 添加以下引用:

    1. EnvDTE

    2. EnvDTE80

  3. TestOutput.cs 中,添加以下 using 语句:

    using EnvDTE;
    using EnvDTE80;
    
  4. TestOutput.cs 中,删除 ShowMessageBox 该方法。 添加以下方法存根:

    private void OutputCommandHandler(object sender, EventArgs e)
    {
    }
    
  5. 在 TestOutput 构造函数中,将命令处理程序更改为 OutputCommandHandler。 下面是添加命令的部分:

    OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
    if (commandService != null)
    {
        CommandID menuCommandID = new CommandID(MenuGroup, CommandId);
        EventHandler eventHandler = OutputCommandHandler;
        MenuCommand menuItem = new MenuCommand(eventHandler, menuCommandID);
        commandService.AddCommand(menuItem);
    }
    
  6. 以下各节具有不同的方法,这些方法显示了处理“输出”窗格的不同方法。 可以将这些方法调用为方法的 OutputCommandHandler() 正文。 例如,以下代码将添加 CreatePane() 下一节中给出的方法。

    private void OutputCommandHandler(object sender, EventArgs e)
    {
        CreatePane(new Guid(), "Created Pane", true, false);
    }
    

使用 IVsOutputWindow 创建输出窗口

此示例演示如何使用IVsOutputWindow接口创建新的“输出”窗口窗格。

void CreatePane(Guid paneGuid, string title,
    bool visible, bool clearWithSolution)
{
    IVsOutputWindow output =
        (IVsOutputWindow)GetService(typeof(SVsOutputWindow));
    IVsOutputWindowPane pane;

    // Create a new pane.
    output.CreatePane(
        ref paneGuid,
        title,
        Convert.ToInt32(visible),
        Convert.ToInt32(clearWithSolution));

    // Retrieve the new pane.
    output.GetPane(ref paneGuid, out pane);

     pane.OutputString("This is the Created Pane \n");
}

如果将此方法添加到上一部分中给定的扩展,单击 “调用 TestOutput ”命令时,应会看到 “输出 ”窗口,其中标题显示 “显示输出来源:CreatedPane ”和 “这是窗格本身的创建窗格 ”。

使用 OutputWindow 创建输出窗口

此示例演示如何使用OutputWindow对象创建“输出”窗口窗格。

void CreatePane(string title)
{
    DTE2 dte = (DTE2)GetService(typeof(DTE));
    OutputWindowPanes panes =
        dte.ToolWindows.OutputWindow.OutputWindowPanes;

    try
    {
        // If the pane exists already, write to it.
        panes.Item(title);
    }
    catch (ArgumentException)
    {
        // Create a new pane and write to it.
        panes.Add(title);
    }
}

虽然集合OutputWindowPanes允许你按标题检索“输出”窗口窗格,但不能保证窗格标题是唯一的。 如果怀疑游戏的唯一性,请使用 GetPane 该方法按其 GUID 检索正确的窗格。

如果将此方法添加到上一部分中给定的扩展中,单击“调用 TestOutput”命令时,应会看到“输出”窗口,其中标题显示“显示输出来源:DTEPane”和窗格中的“添加 DTE 窗格”单词

删除“输出”窗口

此示例演示如何删除 “输出 ”窗口窗格。

void DeletePane(Guid paneGuid)
{
    IVsOutputWindow output =
    (IVsOutputWindow)ServiceProvider.GetService(typeof(SVsOutputWindow));

    IVsOutputWindowPane pane;
    output.GetPane(ref paneGuid, out pane);

    if (pane == null)
    {
        CreatePane(paneGuid, "New Pane\n", true, true);
    }
     else
    {
        output.DeletePane(ref paneGuid);
    }
}

如果将此方法添加到上一部分中给定的扩展中,单击“调用 TestOutput”命令时,应会看到“输出”窗口,其中标题显示“显示输出来源:新建窗格”和窗格中的“添加的窗格”字样。 如果再次单击 “调用 TestOutput ”命令,则会删除该窗格。

获取“输出”窗口的“常规”窗格

此示例演示如何获取“输出”窗口的内置“常规”窗格。

IVsOutputWindowPane GetGeneralPane()
{
    return (IVsOutputWindowPane)GetService(
        typeof(SVsGeneralOutputWindowPane));
}

如果将此方法添加到上一部分中给定的扩展,单击“调用 TestOutput”命令时,应会看到“输出”窗口显示窗格中的“发现常规”窗格

获取“输出”窗口的“生成”窗格

此示例演示如何查找“ 生成 ”窗格并写入该窗格。 由于“生成”窗格默认未激活,因此也会激活它。

void OutputTaskItemStringExExample(string buildMessage)
{
    EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)ServiceProvider.GetService(typeof(EnvDTE.DTE));

    EnvDTE.OutputWindowPanes panes =
        dte.ToolWindows.OutputWindow.OutputWindowPanes;
    foreach (EnvDTE.OutputWindowPane pane in panes)
        {
            if (pane.Name.Contains("Build"))
            {
                pane.OutputString(buildMessage + "\n");
                pane.Activate();
                return;
             }
        }
}