获取服务

通常需要获取 Visual Studio 服务才能访问不同的功能。 一般情况下,Visual Studio 服务提供一个或多个可以使用的接口。 可以从 VSPackage 获取大多数服务。

派生自 Package 且已正确站点的任何 VSPackage 都可以请求任何全局服务。 Package由于该类实现IServiceProvider,因此派生自Package的任何 VSPackage 也是服务提供商。

当 Visual Studio 加载 a Package时,它会在初始化期间将对象 IServiceProvider 传递给 SetSite 方法。 这称为 VSPackage 。 该 Package 类包装此服务提供程序,并提供 GetService 获取服务的方法。

从初始化的 VSPackage 获取服务

  1. 每个 Visual Studio 扩展都以 VSIX 部署项目开头,该项目将包含扩展资产。 创建名为 GetServiceExtension 的 Visual Studio VSIX 项目。 可以通过搜索“vsix”在“新建项目”对话框中找到 VSIX 项目模板

  2. 现在添加名为 GetServiceCommand 的自定义命令项模板。 在“添加新项”对话框中,转到 Visual C#>Extensibility 并选择“自定义命令”。窗口底部的“名称 ”字段中,将命令文件名更改为 GetServiceCommand.cs。 有关如何创建自定义命令的详细信息, 请使用菜单命令创建扩展

  3. GetServiceCommand.cs 中,删除方法的 MenuItemCommand 正文并添加以下代码:

    IVsActivityLog activityLog = ServiceProvider.GetService(typeof(SVsActivityLog)) as IVsActivityLog;
    if (activityLog == null) return;
    System.Windows.Forms.MessageBox.Show("Found the activity log service.");
    
    

    此代码获取 SVsActivityLog 服务并将其强制转换为 IVsActivityLog 接口,该接口可用于写入活动日志。 有关示例,请参阅 “如何:使用活动日志”。

  4. 生成项目并启动调试。 这将显示实验实例。

  5. 实验实例的“工具” 菜单上,找到 “调用 GetServiceCommand ”按钮。 单击此按钮时,应会看到一个显示 “找到活动日志服务”的消息框。

从工具窗口或控件容器获取服务

有时,可能需要从工具窗口或控件容器获取服务,但尚未进行站点设置,或者已使用不知道所需服务的服务提供商进行站点。 例如,你可能想要从控件内部写入活动日志。

静态 GetGlobalService 方法依赖于缓存的服务提供程序,该提供程序是在首次派生自 Package 任何 VSPackage 时初始化的。

由于 VSPackage 构造函数是在 VSPackage 站点之前调用的,因此全局服务通常从 VSPackage 构造函数中不可用。 请参阅 “如何:排查服务 问题”以获取解决方法。

下面是在工具窗口或其他非 VSPackage 元素中获取服务的方法示例。

IVsActivityLog log = Package.GetGlobalService(typeof(SVsActivityLog)) as IVsActivityLog;
if (log == null) return;

从 DTE 对象获取服务

还可以从 DTEClass 对象获取服务。 但是,必须从 VSPackage 或通过调用静态 GetGlobalService 方法获取 DTE 对象即服务。

DTE 对象实现 IServiceProvider,你可以使用它来 GetService查询服务。

下面介绍如何从 DTE 对象获取服务。

// Start with the DTE object, for example: 
// using EnvDTE;
// DTE dte = (DTE)GetService(typeof(DTE));

ServiceProvider sp = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte);
if (sp != null)
{
    IVsActivityLog log = sp.GetService(typeof(SVsActivityLog)) as IVsActivityLog;
    if (log != null)
    {
        System.Windows.Forms.MessageBox.Show("Found the activity log service.");
    }
}