Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should I attach solution or project events in my Visual Studio add-in?

Can anyone suggest the best place to add solution or project events, such as ProjectAdded, to a Visual Studio add-in?

If I do this when the add-in connects then there's no solution loaded, so how can I tell when a solution has been loaded?

For example, if I write an event to handle project items being added, where should I attach this? The event would be fired by the project, and that in turn by the solution, so I can't attach the events when the add-in connects because there is no solution when the add-in connects.

On the other hand, if I add them in the Exec() event then I need to do checks such as whether the event has been attached already, and I'm sure there must be a neater way sometime between the connection events and the Exec() event.

like image 495
awj Avatar asked Aug 12 '10 19:08

awj


People also ask

How do I add a project to solution in Visual Studio code?

Adding a project to a solution file Once you have a solution file, you can add a project to it using the sln add command, and provide the path to the project's . csproj file. This will add the project to an existing solution file in the current folder.

How do I add an existing project to a solution?

To add an existing project to a solutionIn Solution Explorer, select the solution. On the File menu, point to Add, and click Existing Project. In the Add Existing Project dialog box, locate the project you want to add, select the project file, and then click Open. The project is added to the selected solution.

What is a solution file in Visual Studio?

A solution is a structure for organizing projects in Visual Studio. The solution maintains the state information for projects in two files: . sln file (text-based, shared) .


1 Answers

You probably figured this out long ago, but anyway: You can setup your events from within OnConnection like shown below, this is a snippet of an Addin's Connect class (assuming you're using c#):

using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using EnvDTE;
using EnvDTE80;
using Extensibility;
using Microsoft.VisualStudio.CommandBars;

namespace MyAddin1
{
  /// <summary>The object for implementing an Add-in.</summary>
  /// <seealso class='IDTExtensibility2' />
  public class Connect : IDTExtensibility2, IDTCommandTarget
  {
    private DTE2 _applicationObject;
    private AddIn _addInInstance;
    private SolutionEvents _solutionEvents;

    public void OnConnection(object application, ext_ConnectMode connectMode,
          object addInInst, ref Array custom)
    {
      _applicationObject = (DTE2)application;
      _addInInstance = (AddIn)addInInst;

      // check the value of connectMode here, depending on your scenario
      if(connectMode == ...)
        SetupEvents();
    }

    private void SetupEvents()
    {
      // this is important ...
      _solutionEvents = _applicationObject.Events.SolutionEvents;

      // wire up the events you need
      _solutionEvents.Opened += new _dispSolutionEvents_OpenedEventHandler(_solutionEvents_Opened);
      _solutionEvents.AfterClosing += new _dispSolutionEvents_AfterClosingEventHandler(_solutionEvents_AfterClosing);
      _solutionEvents.ProjectAdded += new _dispSolutionEvents_ProjectAddedEventHandler(_solutionEvents_ProjectAdded);
    }

  // add procedures to handle the events here, plus any other
  // handling you need, ie. OnDisconnection and friends
}

The main point is, to wire up the solution and project events you need, it's not important if a solution or project is already loaded. They're not attached to any particular solution or project, they're provided by the Visual Studio object model and are embedded within the EnvDTE namespace.

It wouldn't make much sense to do anything else anyway, since you can configure an addin to load when VS starts, and in this case there will never ever be any solutions/projects loaded.

There's a few catches though:

  • It's important that you keep a reference to the SolutionEvents class as a member variable within your connect class, otherwise the events will never fire, (see also here).
  • You need to make sure you check the connectMode parameter passed into OnConnection. This gets called multiple times with different parameters, and if you do it the wrong way you may get the event wired up multiple times, which definetly will be a problem. Also, usually any Addin IDE, like Menus and stuff, is set up from within OnConnection, so you may end up with duplicate menu items if you don't do it right.

Here's a few pointers, some of the code provided is VB code, in case you're looking for that:

  • HOWTO: Adding buttons, commandbars and toolbars to Visual Studio .NET from an add-in
  • HOWTO: Getting Project and ProjectItem events from a Visual Studio .NET add-in.
  • HOWTO: Add an event handler from a Visual Studio add-in

Finally, here's a list of articles, about 70% of them cover basic and advanced topics regarding addins:

  • Resources about Visual Studio .NET extensibility

Find the section entitled MZ-Tools Articles Series (about add-ins) and have a look at what's covered there.

like image 75
takrl Avatar answered Sep 26 '22 16:09

takrl