Getting to IServiceProvider services with VSIP Extras

If you have access to the underlying Package base class, it exposes a method to get services called GetService.  You use it like so:

IVsShell vsshell = (IVsShell) GetService(typeof(SVsShell));

vsshell can then be used to call methods it exposes (the IVsShell interface).  The GetService method is simply implemented by using the ServiceProvider object which wrapes the use of the IServiceProvider interface passed to the package's IVsPackage.SetSite method.

For other objects that don't have access to the Package base class and receive another IServiceProvider (like the IVsWindowPane interface associated with VS windows which has its own SetSite method) then the GetService method exposed by the Package base class isn't available.  Instead the IVsWindowPane.SetSite method can be written as follows to create its own ServiceProvider object:

ServiceProvider myServiceProvider;

int IVsWindowPane.SetSite(IServiceProvider sp)
{
  myServiceProvider = new ServiceProvider(sp);
  return NativeMethods.S_OK;
}

Now code that has access to myServiceProvider can use it to get services just like in the Package base class.

IVsShell vsshell = (IVsShell) myServiceProvider.GetService(typeof(SVsShell));

The ServiceProvider class handles all of the marshaling of the interface pointer and handles the error cases for you so you don't have to worry about them. 

Unfortunately the VSIP Extras samples are frozen at this point and I'm not allowed to crack them to make this little change.  You can make it yourself in your code, though and it should save you some headaches when trying to get services in other objects besides your package based on the Helper's Package base class.

I hope this helps,

Allen