August
14

I have been invited for a couple of weeks to do some coding standards work in a rather large IT department.

Basically the job is to evaluate their coding standards document and make sure it is enforced. Since coding standards documents are usually dropped on your table by your manager in your first day of work and they usually remain untouched, we have to come up with a solution that will actually force people to comply to these standards.

So I did some reading on FxCop and found this great video by Guy Smith-Ferrier that really brought me up to speed on writing custom FxCop rules in an hour. Writing these rules is a real pain and I’ll have to do my best to use existing rules and avoid creating new ones.

The only problem with using FxCop in order to apply these standards is that it will analyze entire assemblies and will produce a lot of warnings, as this IT department has dozens of large existing & legacy projects.

My challenge will be to make FxCop run without shouting too much on legacy code. I will continue to update as things progress.

2
August
9

After yesterday’s adventure of adding buttons to Visual Studio’s Solution Explorer, I just had to post a short follow-up that shows how easily the same task can be done in #develop’s Projects pad. To remind you, what I wanted to do was add two buttons - one for the project context menu and one for the solution context menu.

While the Solution Explorer adventure required some coding, the Projects pad one is almost nothing but XML.

Simply open up your .addin file and add two Path elements under your AddIn element.

   1:  <AddIn name        = “My Add-in”
   2:         author      = “Omer Rauchwerger (rauchy)”
   3:         url         = “http://blog.rauchy.net”
   4:         description = “Does stuff.”>
   5:   
   6:  
   7:    
   8:      <Path name=”/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectNode”>
   9:              <MenuItem id = “DoStuffOnProject”
  10:                    label = “Do stuff on this project”
  11:                    class = “MyNamespace.ProjectCommand”/>
  12:      </Path>
  13:      <Path name=”/SharpDevelop/Pads/ProjectBrowser/ContextMenu/SolutionNode”>
  14:              <MenuItem id = “DoStuffOnSolution”
  15:                    label = “Do stuff on this solution”
  16:                    class = “MyNamespace.SolutionCommand”/>
  17:      </Path>
  18:  </AddIn>

The first Path element creates a button labeled “Do stuff on this project” and places it on the context menu that pops up when your right-click a project in the Projects pad. It also hooks it up with the “MyNamespace.ProjectCommand” class. The second Path element does the same but for solutions, and hooks it up with the “MyNameSpace.SolutionCommand” class.

ProjectCommand and SolutionCommand are two classes you should create which inherit from AbstractMenuCommand. All you need to implement in these classes is the Run method. The Run method will run whenever someone clicks on the button.

   1:  using ICSharpCode.Core;
   2:   
   3:  namespace MyNamespace
   4:  {    
   5:      public class SolutionCommand : AbstractMenuCommand
   6:      {
   7:          public override void Run()
   8:          {
   9:              // TODO: Handle the Click event.
  10:          }
  11:      }
  12:  }

Gosh I love #develop extensibility :-)

kick it on DotNetKicks.com

0
August
8

I’d like to share today’s experience of adding buttons to the solution and project context menus in Visual Studio 2005’s Solution Explorer window. (I ended up with this)
Seems like everything related to Visual Studio extensibility is overly complicated, but unlike other extensibility tasks, this one is rather simple.

Step 1 will be to find our CommandBar.

The CommandBar is our target where we would like to place our buttons. In my case, I wanted to add a button to the context menu that pops up when you right-click on a solution or project. You can retrieve your CommandBar object from the applicationObject.CommandBars collection by specifying its name.

   1:  CommandBars commandBars = ( CommandBars )applicationObject.CommandBars;
   2:  CommandBar commandBar = commandBars[ “Solution” ];

Solution” represents the context menu that pops up when you right-click solutions in the Solution Explorer and “Project” represents the one for projects.

In step 2 we will create the actual button.

The type of this button control is CommandBarButton. In spite of what you might think, you can’t just initialize it by using new CommandBarButton(), you have to get your instance by calling the Add method on your CommandBar.
Here is how the CommandBar.Add method looks like: (don’t copy & paste this code)

CommandBarControl Add(object Type, object Id, object Parameter, object Before, object Temporary);

Don’t ask me why everything is object based, I’m guessing it has something to do with the fact that the entire model is COM based. oh well.
The CommandBarButton is created this way:

   1:  CommandBarButton button = ( CommandBarButton )commandBar.Controls.Add( MsoControlType.msoControlButton, Missing.Value, Missing.Value, 1, true );
   2:  button.Caption = “My Button”;
 

You can compile your solution and run it, you will be able to see your button in the Solution Explorer.
This is all good, but a button that doesn’t do anything is really not that handy nowadays so we’ll have to subscribe to its click event.

Step 3: Doing stuff when the button is clicked.

Well, you guessed it, we can’t do that simply by registering to the button’s OnClick event, cause there isn’t one. We have to register through the button’s CommandBarEvents object.
The CommandBarEvents class exposes the Click event for your button. Here’s how to add some event handling code for the Click event:

   1:  CommandBarEvents myButtonEvents = ( CommandBarEvents )applicationObject.Events.get_CommandBarEvents( myButton );
   2:  myButtonEvents.Click += 
   3:        delegate( object CommandBarControl, ref bool Handled, ref bool CancelDefault )
   4:            {
   5:                // TODO: Handle the Click event.
   6:                Handled = true;
   7:            };

And now for a tricky part: since you get your instance of CommandBarEvents inside the scope of a method, when the method ends, the Garbage Collector collects it, leaving all the event handlers orphaned. Unless you keep your instance safe from the jaws of the mighty Garbage Collector, your buttons will not respond to clicks.
To do so, just keep your CommandBarEvents instance(s) as member fields of your class. Once your class is disposed, they will be disposed as well.

kick it on DotNetKicks.com

1