Writing an Addin for SharpDevelop 1.0+ with Visual Studio 2003

CodeXchangeAddin.jpg

Introduction

Any modern application theses days is designed with extensibility in mind. This allows developers and even the end user to replace existing pieces or add their own custom functionality.

When extending an existing application we have basically two ways of doing this : Macros and plug-ins. Macros are small interpreted programs created with scripting languages that run within applications such as Excel and PowerPoint while Plug-ins are compiled applications created against the application plug-in mechanism and have access to a rich set of APIs that enables developers to develop and explore new tools quickly, without having to start from scratch.

Which approach is the best? Well, It depends on the situation. Macros are usually very easy to create by end users but have a limited access to the application API while Plug-ins require strong programming skills to make something useful but are usually far more efficient and powerful. Plug-ins are compiled code; so there are no performance losses caused by the script engine virtual machine.

IDEs (Integrated development environment) are no exception. They provide a very rich object model. The big ones like Visual Studio or Eclipse are basically a container where developers can connect their code. Even the compilers are plug-ins!
 

CodeXchange

For those of you who don't know CodeXchange you can visit its website and learn what is all about. All software is free so this is not some kind of cheap commercial.

In the above website you will find also a Visual Studio version of the client software but if you are a SharpDevelop user you are out of luck, so we will write our own SharpDevelop CodeXchange client (Good excuse to learn something new about this IDE!) .

Our simple SharpDevelop CodeXchange client will be based on its public web services located at
http://www.codexchange.net/CodeXchangeservice.asmx

What's a Plug-in/Addin?

The word plug-in is often used by software developers to describe a third party application that "hooks" into a main application to extend its functionality.

An Addin is a small compiled piece of software that, once registered and installed, extends the functionality of the host application (in our sample the SharpDevelop IDE).The only limit from here is the host application exposed functionality and your imagination.

The SharpDevelop object model

There is a detailed PDF available at SharpDevelop's website
here that you will want to read for a full understanding of the entire system and possibilities. This is intended as a simple and quick overview.

The Addin Assembly

A SharpDevelop Addin is a regular class library which imports some SharpDevelop namespaces. We are creating a project browser or output pad like Addin. In SharpDevelop this kind of plug-ins are called Pads. Creating your own SharpDevelopPad is really simple, just create a new class an inherit form the AbstractPadContent class.

The most important property of this class is a virtual property called "Control". This property as his name says holds a Windows Forms control reference (our control) that will be the graphical representation of our plug-in because this is the control that will be added to the SharpDevelop environment inside the newly created Pad.

Import common .NET framework namespaces

using System;

using System.IO;

using System.Collections;

using System.Windows.Forms;

using System.Drawing;


Import SharpDevelop specific namespaces

 

using ICSharpCode.Core.Services;

using ICSharpCode.Core.Properties;

using ICSharpCode.Core.AddIns.Codons;

using ICSharpCode.Core.AddIns.Conditions;

using ICSharpCode.Core.AddIns;

using ICSharpCode.SharpDevelop.Services;

using ICSharpCode.SharpDevelop.Gui;


Create our own SharpDevelop Pad inheriting from AbstractPadContent and adding our custom control to it

 

namespace Sand.Services.CodeXchange.SharpDevelopAddin

{

public class CodeXchangeViewContent : AbstractPadContent

{

                    public static CodeXchangeControl MyControl = null;

                    public CodeXchangeViewContent () : base ("CodeXchange Addin")

                    {

                             MyControl = new CodeXchangeControl ();

                             MyControl.Dock = DockStyle.Fill;

                    }

                    ///

                    /// This is the Windows.Forms control for the view.

                    ///

                    public override Control Control

                    {

                             get

                             {

                                       return MyControl;

                             }

                    }

                    ///

                    /// Reinitializes the content. (Re-initializes all add-in tree stuff)

                    /// and redraws the content. Call this not directly unless you know

                    /// what you do.

                    ///

                    public override void RedrawContent()

                    {

                    }

                    public override void Dispose()

                    {

                             MyControl = null;

                    }

}

}

Debugging our SharpDevelop Addin with Visual Studio.NET

Our Addin is no more than a standard DLL, so we can use the same procedure used when debugging other class libraries.

Debugging our newly created SharpDevelop Addin should be very easy if we setup the "Start Program" setting of our project to the SharpDevelop image path. Every time we run the DLL project Visual Studio will load a new instance of SharpDevelop and attach the debugger to it so we can debug our code.

DebuggingWithVS.jpg

The .addin.xml file

Once we have our code ready and compiled into one or more assemblies we must tell SharpDevelop how to load it and how to configure the environment, for example, If you pay attention to the "Extension" tags you will see the new menus my Addin requires and how I'm telling SharpDevelop where to place these application or contextual menus and how to connect them to our code thru commands.

The Addin xml file is almost self explaining:

<AddIn name        = "CodeXchangeAddin"

       author      = "Marc Piulachs"

       copyright   = "GPL"

       url         = "http://www.codexchange.net"

       description = "SharpDevelop CodeXchange Client"

       version     = "0.1.0">

 

 <Runtime>

  <Import assembly="Sand.Services.CodeXchange.SharpDevelopAddin.dll"/>

 </Runtime>

 

 <Extension path = "/SharpDevelop/Workbench/Views">

     <Class id = "CodeXchange"

       insertafter = "HelpBrowser"

       class = "Sand.Services.CodeXchange.SharpDevelopAddin.CodeXchangeViewContent"/>

 </Extension>

 

 <Extension path = "/SharpDevelop/Workbench/MainMenu/Tools">

  <MenuItem id = "CodeXchangeAddin"

          insertafter = "Separator3" insertbefore = "Separator4"

          label = "CodeXchange"

          class = "Sand.Services.CodeXchange.SharpDevelopAddin.CodeXchangeCommand"/>

 </Extension>            

            

 <Extension path = "/SharpDevelop/ViewContent/DefaultTextEditor/ContextMenu">

   <Conditional action="Disable">

      <Or>

        <Condition activeextension = ".vb"/>

        <Condition activeextension = ".cs"/>

      </Or>              

      <MenuItem id = "InsertFromCodeXchange"

         label = "Search snippet on CodeXchange"

         insertafter = "Separator4"

         class ="Sand.Services.CodeXchange.SharpDevelopAddin.InsertCodeXchangeSnippetCommand" />

   </Conditional>

  </Extension>            

        

  <Extension path = "/SharpDevelop/ViewContent/DefaultTextEditor/ContextMenu">

    <Conditional action="Disable">

      <Or>

        <Condition activeextension = ".vb"/>

        <Condition activeextension = ".cs"/>

      </Or>              

      <MenuItem id = "ContributeToCodeXchange"

        label = "Contribute snippet to CodeXchange"

        insertafter = "Separator4"

        class ="Sand.Services.CodeXchange.SharpDevelopAddin.ContributeSnippetCommand" />

    </Conditional>

   </Extension>

</AddIn>

Building and installing

  • Create a new folder named "CodeXchange" in your SharpDevelop Addins folder in my setup "\SharpDevelop\AddIns\AddIns\Misc\CodeXchange".
  • Compile your code as usual and place the generated dlls together with the .Addin manifest file to the newly created folder.
  • Start SharpDevelop as normal.

Conclusions

The CodeXchange sample client included with this article does not pretend to implement the complete command set providing instead support for the basic features. You can use this code to create your own customized client or use it as reference and guide for your own projects. Have Fun!

Credits and Errata

Article reviewed by Ernesto Giralt

References


Similar Articles