扩展“输出”窗口

适用范围:yesVisual Studio noVisual Studio for Mac noVisual Studio Code

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

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

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

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

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

  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;
             }
        }
}