How To: Get a ServiceProvider from the VS Start Page

When working with Visual Studio extensibility, getting a ServiceProvider is the main way to find and use services that are available in Visual Studio. The new VS Start Page is written in WPF and getting to a ServiceProvider from within the page or one of its child controls is not easily found. There is a fairly good topic on this in MSDN: https://msdn.microsoft.com/en-us/library/ff432842(v=VS.100).aspx, though the nugget about getting to the ServiceProvider is a little lost in the full article. So, I decided to pull it out into a post here to make it easier to find this useful snippet.

First, use the Custom StartPage template to create a new project to work with (this topic explains how to use that template).

Then, in the code file for your UserControl, you can add the following code as a property of the control class:

private DTE2 dte = null;

private IServiceProvider serviceProvider = null;

/// <summary>

/// Gets the StartPage's DTE object from its DataContext.

/// </summary>

private DTE2 DTE

{

get

{

if (dte == null)

{

// if we don't already have the ServiceProvider, get it from the page's DataContext.

ICustomTypeDescriptor typeDescriptor = DataContext as ICustomTypeDescriptor;

PropertyDescriptorCollection propertyCollection = typeDescriptor.GetProperties();

// first get the DTE object from the DataContext.

dte = propertyCollection.Find("DTE", false).GetValue(DataContext) as DTE2;

}

return dte;

}

}

/// <summary>

/// Gets the StartPage's ServiceProvider for use in our custom control.

/// </summary>

private IServiceProvider ServiceProvider

{

get

{

if (serviceProvider == null)

{

// get and then cast the DTE object to a ServiceProvider.

serviceProvider = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)DTE);

}

return serviceProvider;

}

}

Note: this code requires you to include the following namespaces in your source file: EnvDTE80, Microsoft.VisualStudio.Shell, Microsoft.VisualStudio.Shell.Interop, and System.ComponentModel.

Now that you have this method to get at the ServiceProvider from your custom StartPage, you can use it to get any of the services provided by Visual Studio and integrate them into your page.