title author date CreateTime categories
VisualStudio 扩展开发 添加输出窗口
lindexi
2019-02-03 11:41:40 +0800
2019-02-03 09:31:58 +0800
VisualStudio

小伙伴都用过 VisualStudio 都在输出窗口看到不同的子窗口,如 gitlab 的输出窗口,调试的输出窗口,本文告诉大家如何写插件在输出窗口里面添加一个窗口

添加菜单 告诉大家如何简单在 VisualStudio 的工具添加一个按钮,通过用户点击按钮才能使用插件

于是请先看一下如何添加按钮的博客,这样本文就可以直接开始告诉大家在这篇博客 用到方法里面快速添加一个自定义的输出窗口

在输出窗口里面的窗口在 VisualStudio 官方的命名是 Pane 也就是本文是告诉大家如何在 VisualStudio 的 OutputWindow 添加一个 Pane 在这个 Pane 里面输出

在 VisualStudio 的 OutputWindow 包含了一组可读可写的文本 默认的 VisualStudio 会带很多的 Pane 如 Build 这是一个项目关于编译的输出,还有 General 这是 VisualStudio 这个工具的一些信息。通过 IVsBuildableProjectCfg 接口可以自动绑定输出到 Build 如调用编译。通过 SVsGeneralOutputWindowPane 服务可以直接访问 General 获取里面的输出。

开发者可以通过 VisualStudio SDK 创建管理自己的自定义窗口。

通过 IVsOutputWindowIVsOutputWindowPane 接口可以控制输出窗口。通过 SVsOutputWindow 服务可以拿到 IVsOutputWindow 接口。通过 IVsOutputWindow 可以获取到 IVsOutputWindowPane 或者创建关闭

通过 IVsOutputWindowPane 的方法可以激活 Pane 或隐藏 Pane 滚动里面的文本或清空输出

在开发 VisualStudio 插件的时候,因为文档不多,同时开发的时候会发现有一些文档没有更新,所以难度会比较大

创建自定义的输出窗口

在 Execute 方法,也就是 NowkuPurqicowFourocafem 的 Execute 方法,这个方法在这篇博客 已经有告诉大家,这个方法就是用户点击按钮的时候就会使用可以在这里添加一个 Pane 请看代码

也就是调用一个方法,这个方法是自己写的

通过 SVsOutputWindow 拿到 IVsOutputWindow 接口

    IVsOutputWindow output =
(IVsOutputWindow) Package.GetGlobalService(typeof(SVsOutputWindow));

这里的 Package 是 Microsoft.VisualStudio.Shell 是一个静态类里面的方法,除了使用静态类获取,还可以通过 NowkuPurqicowFourocafem 类里面的 package 获取,但是里面的获取方法是异步的

        /// <summary>
/// VS Package that provides this command, not null.
/// </summary>
private readonly AsyncPackage package;

这个字段是在 InitializeAsync 静态方法注入的

拿到了 IVsOutputWindow 就可以添加输出窗口

        void CreatePane(Guid paneGuid, string title,
bool visible, bool clearWithSolution)
{
ThreadHelper.ThrowIfNotOnUIThread(); IVsOutputWindow output =
(IVsOutputWindow)Package.GetGlobalService(typeof(SVsOutputWindow)); // Create a new pane.
output.CreatePane(
ref paneGuid,
title,
Convert.ToInt32(visible),
Convert.ToInt32(clearWithSolution));
}

这里传入的 paneGuid 是自己定义的,通过这个 paneGuid 就可以获取输出窗口

上面的代码只是创建,如果想要拿到 Pane 还需要调用这个方法

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

这样就可以拿到 IVsOutputWindowPane 接口

拿到了 IVsOutputWindowPane 就可以输出请看代码

            pane.OutputString("欢迎访问我博客 http://lindexi.gitee.io 里面有大量 UWP WPF 博客 \n"); 

除了通过 SVsOutputWindow 创建输出窗口,还可以使用 OutputWindow 创建输出窗口

添加 CreatePane 重载

void CreatePane(string title)
{ }

现在通过 package 拿到 DTE 通过 DTE 可以拿到输出窗口

        private async void CreatePane(string title)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
DTE2 dte = (DTE2) await package.GetServiceAsync(typeof(DTE))
}

通过 package 需要使用异步的方法拿到服务

            OutputWindowPanes panes =
dte.ToolWindows.OutputWindow.OutputWindowPanes;

但是 OutputWindowPanes 不是列表,需要通过下面的代码去拿到 Pane 或创建

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

虽然通过异常判断是否已经存在 Pane 不存在就创建的代码比较差,但是可以简单告诉大家如何通过 OutputWindowPanes 创建

这里拿到的 Pane 是 OutputWindowPane 和上面 IVsOutputWindowPane 是有点不一样的,通过 OutputWindowPane 可以拿到输出

       private void GetText(OutputWindowPane pane)
{
ThreadHelper.ThrowIfNotOnUIThread();
TextDocument document = pane.TextDocument;
EditPoint point = document.StartPoint.CreateEditPoint(); // 下面 str 就是输出
var str = point.GetText(document.EndPoint);
}

这里获取输出请看 VisualStudio 扩展开发 获得输出窗口内容

这个 CreatePane 方法全部代码

       private async void CreatePane(string title)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
DTE2 dte = (DTE2) await package.GetServiceAsync(typeof(DTE));
OutputWindowPanes panes =
dte.ToolWindows.OutputWindow.OutputWindowPanes; try
{
// If the pane exists already, write to it.
OutputWindowPane pane = panes.Item(title);
}
catch (ArgumentException)
{
// Create a new pane and write to it.
var pane = panes.Add(title);
pane.OutputString("欢迎访问我博客 http://lindexi.gitee.io 里面有大量 UWP WPF 博客 \n");
}
}

在 Execute 方法使用下面代码

            CreatePane("林德熙是逗比");

运行可以看到下面代码

但是通过 OutputWindow 的方法获取不是很好,因为有多语言,可能在日本使用的调试窗口写的是デバッグ可能写的插件只能在自己的语言使用,所以还是建议使用 GUID 的方法创建

获取 General 窗口

在 VisualStudio 有两个输出窗口是默认的,就是 General 和 Build 输出窗口

通过服务的方式可以拿到 General 窗口

        private async Task GetGeneralPane()
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var pane = (IVsOutputWindowPane) await package.GetServiceAsync(
typeof(SVsGeneralOutputWindowPane));
}

获取 Build 窗口

通过下面可以获取 Build 窗口

IDE GUIDs 找到 Build 窗口的 id 然后通过 id 找到窗口

现在就不使用上面的通过 Name 的方法找到窗口

           await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
DTE2 dte = (DTE2) await package.GetServiceAsync(typeof(DTE));
OutputWindowPanes panes =
dte.ToolWindows.OutputWindow.OutputWindowPanes; foreach (EnvDTE.OutputWindowPane pane in panes)
{
if (pane.Guid == "{" +
"1BD8A850-02D1-11D1-BEE7-00A0C913D1F8}")
{
}
}

这样就可以拿到 Build 窗口,尝试在这个窗口输出 编译失败 让你的小伙伴安装了插件就无法编译成功,虽然实际小伙伴还是可以运行代码

微软官方的文档有很多错误,看这篇Extending the Output Window文档不如看本文

Extending the Output Window

2019-2-3-VisualStudio-扩展开发-添加输出窗口的更多相关文章

  1. VisualStudio 扩展开发 获得输出窗口内容

    本文告诉大家如何拿到 VisualStudio 输出窗口的内容 在上一篇告诉大家如何开发添加菜单 点击的时候可以使用方法,如果需要拿到 VisualStudio 的输出窗口的内容,如想要开发一个插件, ...

  2. VisualStudio 扩展开发

    本文主要:如何开发一个 visual Studio 扩展,其实扩展也叫插件. 那么就是如何开发一个 vs插件. 我写这博客时候,是我在开发一个插件:编码规范工具.记录的是我从不知道到发布插件,如果遇到 ...

  3. 2019-3-1-VisualStudio-扩展开发-获得输出窗口内容

    title author date CreateTime categories VisualStudio 扩展开发 获得输出窗口内容 lindexi 2019-03-01 09:21:41 +0800 ...

  4. 利用Visual Studio 2017的扩展开发(VSIX、ItemTemplate) 快速实现项目的半自动化搭建

    目录 0.引言 1.什么是Visual Studio项目模板 2.IWizad接口 3.通过Visual Studio扩展开发实现领域驱动开发 3.1 使用VSIX+ProjectTemplate创建 ...

  5. PHP扩展开发相关总结

    1.线程安全宏定义 在TSRM/TSRM.h文件中有如下定义 #define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, ...

  6. centos php扩展开发流程

    原文:centos php扩展开发流程 一.安装php centos 默认 yum 安装 php 版本为 5.3, 很多php框架基本上要求5.4以上版本,这时候不能直接 用 yum install ...

  7. PHP扩展开发-简单类扩展

    今天来学习简单类扩展开发 实现目标为如下php的类 <?php class classext(){ private $username; CONST URL="http://www.g ...

  8. PHP扩展开发教程(总结)

    PHP是一种解释型的语言,对于用户而言,我们精心的控制内存意味着easier prototyping和更少的崩溃!当我们深入到内核之后,所有的安全防线都已经被越过,最终还是要依赖于真正有责任心的软件工 ...

  9. php扩展开发环境搭建

    首先要安装编译php时要的几个扩展库 (1)libxml2,若无php安装一些解析xml的扩展时会提示xml2-config not found sudo apt-get install libxml ...

随机推荐

  1. HDU6187 Destroy Walls

        把这道题放了很久才来更新blog,似乎越来越懒了啊. 我们发现他给的城堡的坐标非常有趣啊,都是无理数. 对于其他所有点的坐标都是有理数的情况下,一个坐标为无理数的点绝对特别. 特别之处就是:经 ...

  2. html5绘图工具选择

    1. Chart.js 基于html5, 完全开源免费 功能过于简单,只有6种图,能满足小系统需求,使用简便,效果比较炫. http://www.bootcss.com/p/chart.js/ 2. ...

  3. 适配器模式--在NBA我需要翻译

     适配器模式:将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 在软件开发中,也就是系统的数据和行为都正确,但接口不符时,我们应 ...

  4. CesiumLab V1.2 新功能 倾斜数据处理

    一转眼又是一周的时间,我们的实验室功能又强大了. 照旧我们先放毒,放图,图,太晚了,字都敲不到一起了   lod以及包围盒   大雁塔实例,按楼层单体化   倾斜数据处理参数设置 简单介绍一下 Ces ...

  5. day18 15.自定义连接池

    我们写的是连接池吗?Connection对象绝对不能关.现在写的玩意不是连接池.因为现在讲的是JDBC,连接池也是JDBC里面的,人家那是SUN公司定义的标准.标准,你那不是标准.既然是标准,你做连接 ...

  6. expect.js

    前言 1> 借鉴里面的应用思想,使用断言提高代码的健壮性及维护性 2> 实现方式--不采用直接嵌入expect的方式,统一进行重写(提取常用断言方法,重新构造API) 官网介绍 https ...

  7. 【python之路20】函数作为参数

    1.函数可以作为参数 1)函数名相当于变量指向函数 2)函数名后面加括号表示调用函数 #!usr/bin/env python # -*- coding:utf-8 -*- def f1(args): ...

  8. Django与HTML业务基本结合--基本的用户名密码提交方法2

    from django.shortcuts import render # Create your views here. from django.shortcuts import render de ...

  9. Winform实现调用asp.net数据接口实例

    本文实例讲述了Winform实现调用asp.net数据接口的方法,分享给大家供大家参考.具体实现方法如下: 一.问题: 最近一个WPF项目需要改写成android项目,思路是在asp.net项目中编写 ...

  10. BP神经网络分类应用

    DNA序列分类  作为研究DNA序列结构的尝试,提出以下对序列集合进行分类的问题:有20个已知类别的人工制造序列,其中序列标号1-10为A类,11-20为B类.请从中提取特征,构造分类方法,并用这些已 ...