Dotneteers.net
All for .net, .net for all!

LVN! Sidebar #1 - Automatically loading packages

When writing LearnVSXNow articles and working on projects I collected a lot of experience related to VSX. Some of them simply do not directly match with the main stream of the articles. I have got many “how-to-dos”, created small but useful code artifacts, found irritating bugs, etc.

I decided to create a separate thread within the LearnVSXNow series not tied to the main stream just for publishing these small “knowledge elements”.

So, now you read the first piece on this thread I named “LearnVSXNow! Sidebar” or simply as you will find in the title of this blog items: LVN! Sidebar.

What this blog item is about?

As you now, Visual Studio does not automatically load VSPackages when Visual Studio starts. The package is loaded only when the first object of the package is referenced. This can be a menu command, tool window, document editor, service object or whatever. During this load operation first a package instance is constructed, sited within the Visual Studio IDE then its Initialize method is called.

This on-demand model works very well with VSPackages. However there are situations when this approach is not convenient or simply does not work.

Why to load VSPackages automatically?

I tell you one example, but you may find many more similar. The package can subscribe to events when the current solution changes. This can be done through the IVsSolution interface with the AdviseSolutionEvents method where you pass an IVsSolutionEvents object that can be notified about changes in the solution. Let us assume you want to respond to the event when a new solution is loaded.

The problem is, while your package is not in the memory, it cannot subscribe to the solution events. First, as a user you must do some interaction that initiates loading the package and in the overridden Initialize method you make the subscription. But while the package is not loaded you are not able to catch event notifications.

Solution alternatives

One alternative is to write a Visual Studio add-in instead of a VSPackage. Add-ins can be marked to load at Visual Studio startup time. This seems a good alternative but only in the case when the functionality you want to use can be efficiently done with add-ins. In this case you must be aware of the fact that developing an add-in is slightly different from developing a VSPackage.

Another alternative to this issue is to write a very simple Visual Studio add-in and mark it to load at Visual Studio startup time. This add-in is initialized so that it calls a (fake) global service published by your package. When this service is called, your package is loaded into the memory.

However, both alternatives work as expected they require some development and testing efforts. Fortunately there is a simpler declarative solution for this issue.

The ProvideAutoLoadAttribute class

There is an attribute in the Microsoft.VisualStudio.Shell namespace called ProvideAutoLoad. You can decorate your Package derived classes with this attribute. The constructor of ProvideAutoLoad requires a GUID that is the so-called context ID. Visual Studio will load your package automatically when it enters into the specified context. (To get more information about what these contexts are, read the “Visibility contexts” chapter in LearnVSXNow! #13.)

The following example makes your package load automatically when no solution is open in Visual Studio. Actually, it loads when Visual Studio loads:

// --- Microsoft.VisualStudio.VSConstants.UICONTEXT_NoSolution

[ProvideAutoLoad("ADFC4E64-0397-11D1-9F4E-00A0C911004F")]

public sealed class MyPackage : Package { ... }

The GUID passed to ProvideAutoLoad is the GUID for the context where no solution is loaded. Changing the context to the UICONTEXT_SolutionHasMultipleProjects value will cause your package to load only when a solution is loaded (or created) that has two or more projects within:

// --- Microsoft.VisualStudio.VSConstants.UICONTEXT_SolutionHasMultipleProjects

[ProvideAutoLoad("93694fa0-0397-11d1-9f4e-00a0c911004f")]

public sealed class MyPackage : Package { ... }

You can provide zero, one or more ProvideAutoLoad decorations to your package class. If providing more than one, your package is loaded if the current Visual Studio context changes to any of the specified contexts. For example, we can set the decoration so that our package is loaded when we turn on the Full Screen mode or the project enters into Debug mode:

// ---Microsoft.VisualStudio.VSConstants.UICONTEXT_Debugging

[ProvideAutoLoad("adfc4e61-0397-11d1-9f4e-00a0c911004f")]

// --- Microsoft.VisualStudio.VSConstants.UICONTEXT_FullScreenMode

[ProvideAutoLoad("adfc4e62-0397-11d1-9f4e-00a0c911004f")]

public sealed class MyPackage : Package { ... }

As you see, loading your packages automatically is easy!

A few hints when you try this feature: do not forget that changing the ProvideAutoLoad attribute requires your application to rebuild. If you find that you have your app rebuilt but it behaves like before (I mean it loads in the same context as it did before even if changing the ProvideAutoLoad context), reset the Visual Studio Experimental hive (with the tool provided in VS SDK).


Posted Mar 23 2008, 08:10 AM by inovak
Filed under: ,

Comments

steel wrote re: LVN! Sidebar #1 - Automatically loading packages
on Thu, Sep 11 2008 12:16

Hi,

this tip is very useful. However it will cause a 'Bug'. When i add    

Microsoft.VisualStudio.VSConstants.UICONTEXT_NoSolution

[ProvideAutoLoad("ADFC4E64-0397-11D1-9F4E-00A0C911004F")]

to MyPackage, it does  load my pacakge in the context 'NoSolution', however it will causes all my buttons defined contain

<CommandFlag>DynamicVisibility</CommandFlag>

to be showed in 'NoSolution' context, which isn't care about the other defined

   <VisibilityItem guid="guidNewMenuPckCmdSetString" id="cmdidNew" context="UICONTEXT_SolutionHasMultipleProjects"/>

.

JSLint in Visual Studio Part 2 | Scott Logic wrote JSLint in Visual Studio Part 2 | Scott Logic
on Mon, Oct 25 2010 14:40

Pingback from  JSLint in Visual Studio Part 2 |  Scott Logic

James Hollingworth wrote re: LVN! Sidebar #1 - Automatically loading packages
on Mon, Apr 4 2011 16:14

thankyou *so* much, I've been banging my head over this one for ages!

buy stendra online wrote re: LVN! Sidebar #1 - Automatically loading packages
on Fri, Feb 15 2013 19:53

Fkl3HT Very neat article.Really thank you! Awesome.

http://www.springbridge.co.uk/categories/Topsoil-/ wrote re: LVN! Sidebar #1 - Automatically loading packages
on Sat, Feb 16 2013 12:29

I really like and appreciate your post.Much thanks again. Want more.

buy clomid wrote re: LVN! Sidebar #1 - Automatically loading packages
on Thu, Feb 28 2013 21:34

pu3HB0 Very informative blog post. Keep writing.