Home > Sparx Systems Enterprise Architect > Tutorial: Create your first C# Enterprise Architect addin in 10 minutes

Tutorial: Create your first C# Enterprise Architect addin in 10 minutes

Enterprise Architect from Sparx Systems is a great UML Case tool, but you can make it even better by adding your own functionality in the form of an add-in.

This post will take you through the basic steps to create your first C# EA add-in  in about 10 minutes.

You can use a number of programming languages to create add-ins for EA, but personally I like C# the best.

Prerequisites

Before you start you should have following software on your computer ready to use:

  • Enterprise Architect (download the fully functional trial if you don’t have it installed yet)
  • Visual Studio (I’m using the free Visual C# 2010 Express for this tutorial)

EA’s addin architecture

To fully understand the steps necessary to get your add-in running you should first understand how EA’s add-in architecture works.

When EA starts up it will read the registry key [HKEY_CURRENT_USER\Software\Sparx Systems\EAAddins]. Each of the keys in this location represents an add-in for EA to load.

The (default) value of the key contains the name of the assembly and the name of the add-in class separated with a dot.

EA then asks Windows  for the location of the assembly, which is stored on the COM codebase entries in the registry, and it will use the public operations defined in the add-in class.

So in order for our add-in to work we’ll need to:

  • Create the add-in dll containing the add-in class
  • Add a key to registry containing the name of the assembly and the name of the add-in class
  • Register the in the COM codebase entries in the registry

Step 1: Create the add-in dll

So open up Visual Studio, start a new project, and choose Class Library as type of project.

The first thing we need to do is to add the EA API assembly to our references, so choose Add Reference….

Select the Browse tab, browse tot the EA installation folder (default: C:\Program Files\Sparx Systems\EA) and choose the file Interop.EA.dll.
This will allow us to use the classes/interfaces defined by EA’s API.

And since we will be using a messagebox for our first addin, select the .NET tab, scroll down and select System.Windows.Forms

Then there are some build options we need to configure.
First we’re going to tell Visual Studio to build our dll so it can be used as a COM object.
Doubleclick on on the properties folder under your project, click on the button Assembly Information and tick the little checkbox on the bottom that says Make assembly COM-visible

Then we would also like Visual Studio to register the dll in the COM codebase entries in the registry each time it builds our little project.

To do so go into the Build tab of the project properties and tick the checkbox Register for COM interop.

Then we rename the default Class1.cs to MyAddinClass.cs and replace the existing template code by the following:

using System;
using System.Windows.Forms;

namespace MyAddin
{
    public class MyAddinClass
    {
        // define menu constants
        const string menuHeader = "-&MyAddin";
        const string menuHello = "&Say Hello";
        const string menuGoodbye = "&Say Goodbye";

        // remember if we have to say hello or goodbye
        private bool shouldWeSayHello = true;

        ///
        /// Called Before EA starts to check Add-In Exists
        /// Nothing is done here.
        /// This operation needs to exists for the addin to work
        ///
        /// <param name="Repository" />the EA repository
        /// a string
        public String EA_Connect(EA.Repository Repository)
        {
            //No special processing required.
            return "a string";
        }

        ///
        /// Called when user Clicks Add-Ins Menu item from within EA.
        /// Populates the Menu with our desired selections.
        /// Location can be "TreeView" "MainMenu" or "Diagram".
        ///
        /// <param name="Repository" />the repository
        /// <param name="Location" />the location of the menu
        /// <param name="MenuName" />the name of the menu
        ///
        public object EA_GetMenuItems(EA.Repository Repository, string Location, string MenuName)
        {

                switch (MenuName)
                {
                    // defines the top level menu option
                    case "":
                        return menuHeader;
                    // defines the submenu options
                    case menuHeader:
                        string[] subMenus = { menuHello, menuGoodbye};
                        return subMenus;
                }

            return "";
        }

        ///
        /// returns true if a project is currently opened
        ///
        /// <param name="Repository" />the repository
        /// true if a project is opened in EA
        bool IsProjectOpen(EA.Repository Repository)
        {
            try
            {
                EA.Collection c = Repository.Models;
                return true;
            }
            catch
            {
                return false;
            }
        }

        ///
        /// Called once Menu has been opened to see what menu items should active.
        ///
        /// <param name="Repository" />the repository
        /// <param name="Location" />the location of the menu
        /// <param name="MenuName" />the name of the menu
        /// <param name="ItemName" />the name of the menu item
        /// <param name="IsEnabled" />boolean indicating whethe the menu item is enabled
        /// <param name="IsChecked" />boolean indicating whether the menu is checked
        public void EA_GetMenuState(EA.Repository Repository, string Location, string MenuName, string ItemName, ref bool IsEnabled, ref bool IsChecked)
        {
            if (IsProjectOpen(Repository))
            {
                switch (ItemName)
                {
                    // define the state of the hello menu option
                    case menuHello:
                        IsEnabled = shouldWeSayHello;
                        break;
                    // define the state of the goodbye menu option
                    case menuGoodbye:
                        IsEnabled = !shouldWeSayHello;
                        break;
                    // there shouldn't be any other, but just in case disable it.
                    default:
                        IsEnabled = false;
                        break;
                }
            }
            else
            {
                // If no open project, disable all menu options
                IsEnabled = false;
            }
        }

        ///
        /// Called when user makes a selection in the menu.
        /// This is your main exit point to the rest of your Add-in
        ///
        /// <param name="Repository" />the repository
        /// <param name="Location" />the location of the menu
        /// <param name="MenuName" />the name of the menu
        /// <param name="ItemName" />the name of the selected menu item
        public void EA_MenuClick(EA.Repository Repository, string Location, string MenuName, string ItemName)
        {
            switch (ItemName)
            {
                // user has clicked the menuHello menu option
                case menuHello:
                    this.sayHello();
                    break;
                // user has clicked the menuGoodbye menu option
                case menuGoodbye:
                    this.sayGoodbye();
                    break;
            }
        }

        ///
        /// Say Hello to the world
        ///
        private void sayHello()
        {
            MessageBox.Show("Hello World");
            this.shouldWeSayHello = false;
        }

        ///
        /// Say Goodbye to the world
        ///
        private void sayGoodbye()
        {
            MessageBox.Show("Goodbye World");
            this.shouldWeSayHello = true;
        }

        ///
        /// EA calls this operation when it exists. Can be used to do some cleanup work.
        ///
        public void EA_Disconnect()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

    }
}

Now all we need to do is build the project, and the add-in dll is finished.

Step 2: Add the registry key

In order to let EA know there is a new add-in to be loaded we need to add a key in the registry in the location: HKEY_CURRENT_USER\Software\Sparx Systems\EAAddins

To do so open up the Windows registry editor by clicking Start|Run and type regedit

Then browse to the HKEY_CURRENT_USER\Software\Sparx Systems\EAAddins key, right click and add a key with the name of the project in Visual Studio, in our case MyAddin

The registry editor will automatically create a default value for the new key. Doubleclick on the (Default) value on the right pane, and enter the value in the form of [ProjectName].[ClassName], so in this case MyAddin.MyAddinClass

Step 3: Try it out in EA

Alright, now the add-in is ready to be used. So fire up EA, open a project and right click on an element in the projectbrowser, or a diagram.

You should now see an additional menu option with the options we defined.

Congratulations! You have just created your first C# add-in for EA

Distributing the add-in

Once you have finished your add-in you will probably want to share it with others.

There are three steps needed to install your add-in on another computer:

  1. Copy the required files to a convenient location.
    You can find the files needed in your Visual Studio project folder: ..\MyAddin\MyAddin\bin\Release
  2. Register your add-in dll in the COM codebase entries in the registry using regasm.exe
    Open up a command prompt in folder where you copied the add-in dll and register the dll with the /codebase option. In my case that command would be: %WINDIR%\Microsoft.NET\Framework\v4.0.30319\regasm MyAddin.dll /codebase
  3. Add the registry key
    The easiest way to add the registry key on another computer is to export the key from your registry using regedit. This will save the information stored in the key in a .reg file, which you can execute by doubleclicking.

These three steps can of course be automated by your favorite installer program.

More resources

  1. Lauren Arce
    06/10/2011 at 19:15 | #1

    Hi Geert,

    I am developing my first add-in for EA so I went through the steps above and got the following errors when building the code:

    Error 1 A namespace cannot directly contain members such as fields or methods C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 3 1 MyAddin
    Error 2 { expected C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 7 22 MyAddin
    Error 3 A namespace cannot directly contain members such as fields or methods C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 9 1 MyAddin
    Error 4 { expected C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 11 34 MyAddin
    Error 5 Invalid token ’007′ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 13 1 MyAddin
    Error 6 Invalid token ’010′ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 19 1 MyAddin
    Error 7 Invalid token ’011′ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 21 1 MyAddin
    Error 8 Invalid token ’012′ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 23 1 MyAddin
    Error 9 Invalid token ’015′ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 29 1 MyAddin
    Error 10 ; expected C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 45 63 MyAddin
    Error 11 Invalid token ’024′ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 47 1 MyAddin
    Error 12 ; expected C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 75 102 MyAddin
    Error 13 Invalid token ’039′ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 77 1 MyAddin
    Error 14 Invalid token ‘)’ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 81 37 MyAddin
    Error 15 Invalid token ‘;’ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 89 46 MyAddin
    Error 16 Invalid token ‘:’ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 93 40 MyAddin
    Error 17 Invalid token ’049′ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 97 1 MyAddin
    Error 18 Invalid token ‘;’ in class, struct, or interface member declaration C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 97 44 MyAddin
    Error 19 A namespace cannot directly contain members such as fields or methods C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 101 1 MyAddin
    Error 20 A namespace cannot directly contain members such as fields or methods C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 107 1 MyAddin
    Error 21 Expected class, delegate, enum, interface, or struct C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 163 20 MyAddin
    Error 22 Expected class, delegate, enum, interface, or struct C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 233 20 MyAddin
    Error 23 Expected class, delegate, enum, interface, or struct C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 269 21 MyAddin
    Error 24 Expected class, delegate, enum, interface, or struct C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 287 21 MyAddin
    Error 25 Expected class, delegate, enum, interface, or struct C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 305 20 MyAddin
    Error 26 Type or namespace definition, or end-of-file expected C:\Users\lauren.arce\AppData\Local\Temporary Projects\ClassLibrary1\MyAddinClass.cs 317 9 MyAddin

    Any idea where I may have gone wrong?

    Ultimately, my goal is to write an add-in to import milestones dates from an MS Project file into EA as class attribute values.

    Thanks in advance for your help!

    -Lauren

  2. Lauren Arce
    06/10/2011 at 19:22 | #2

    Geert,

    I’ve repasted the code and now I only get the following errors:

    Error 1 The type or namespace name ‘EA’ could not be found (are you missing a using directive or an assembly reference?) C:\Users\lauren.arce\Documents\Visual Studio 2010\Projects\MyAddin\MyAddin\MyAddinClass.cs 23 34 MyAddin
    Error 2 The type or namespace name ‘EA’ could not be found (are you missing a using directive or an assembly reference?) C:\Users\lauren.arce\Documents\Visual Studio 2010\Projects\MyAddin\MyAddin\MyAddinClass.cs 38 39 MyAddin
    Error 3 The type or namespace name ‘EA’ could not be found (are you missing a using directive or an assembly reference?) C:\Users\lauren.arce\Documents\Visual Studio 2010\Projects\MyAddin\MyAddin\MyAddinClass.cs 60 28 MyAddin
    Error 4 The type or namespace name ‘EA’ could not be found (are you missing a using directive or an assembly reference?) C:\Users\lauren.arce\Documents\Visual Studio 2010\Projects\MyAddin\MyAddin\MyAddinClass.cs 82 37 MyAddin
    Error 5 The type or namespace name ‘EA’ could not be found (are you missing a using directive or an assembly reference?) C:\Users\lauren.arce\Documents\Visual Studio 2010\Projects\MyAddin\MyAddin\MyAddinClass.cs 117 34 MyAddin

    Any idea what the issue may be?

    Thanks again.
    -Lauren

  3. Lauren Arce
    06/10/2011 at 20:01 | #3

    Geert,

    I was able to fix the errors — as it turns out I never added the “Interop.EA.dll” as a reference.

    I am now able to build without any errrors, but I cannot see the add-in in EA yet. When I go to the manage add-ins menu in EA, it says that MyAddin is “Error-Missing”??

    -Lauren

  4. Lauren Arce
    06/10/2011 at 20:06 | #4

    Geert,

    Not sure what happened, but it now shows up in EA! Maybe my computer is just slow … nice!

    Now off to figure out how to tweak the code to do what I want it to do …

    -Lauren

    • 07/10/2011 at 08:33 | #5

      Hi Lauren,

      I’m glad to see that you managed to get it working.

      Geert

      • Lauren Arce
        07/10/2011 at 19:46 | #6

        Hi Geert,

        On an unrelated topic, do you know the distinction between “attribute values” and “tagged values” in EA? EA Version 9.1.910 now has the ability to export/import tagged values.

        Thanks.
        -Lauren

  5. Lauren Arce
    20/10/2011 at 20:58 | #7

    Hi Geert,

    Any insight on whether it is good practice to use attributes initial values or tagged values? The reason I ask is because I have the need to import and export data (both ways) from an MS Excel file on a routine basis to update the model so I want to be able to do this in the most automated manner. The CSV import/export works great in doing this with tagged values, but with attributes the closest option is your “Simple VBA Excel to EA importer” macro. And, as far as I can tell, your macro will not import an attribute initial value and I cannot export the same information out of EA to MS Excel.

    Thanks.
    -Lauren

    • 21/10/2011 at 02:32 | #8

      Lauren,

      Attribute initial values and tagged values are different things, each designed for a specific purpose. I think you should use them for their intended purpose only.
      If you want to import initial values into EA it should not take more then half an hour to add that function to the Excel VBA. Have you tried that?

      • Lauren Arce
        21/10/2011 at 19:16 | #9

        Geert,

        I have not taken a stab at trying to add the function to the Excel VBA. I’ll take a look. How difficult do you think it would be to modify the code to do an export from Excel as well? Ultimately, I need the import/export capability that includes attribute name, attribute data type, attribute length, attribute initial value, and possibly tagged-values between EA and Excel.

        Could you elaborate on when one should use attributes vs. tagged values? An example may be helpful.

        Thanks again for all your insight.

        -Lauren

  6. Murat Cinar
    08/12/2011 at 22:05 | #10

    Hi,
    I am working on an add-in for EA, when I was developing the add-in, Visual studio was successfully able to register it as a COM object, but after I finished developing, I copied the dll’s to a specific location on another computer, registered them using regasm.exe (with every possible combination of with or without /codebase option or with or without /tlb option) I also tried to register it using both regasm.exe’s under Framework64 and Framework, but it did not worked. Since I put the last registry manually, I am able to see that EA knows about the add-in but says Error-Missing in the manage add-ins part. I even tried to create regfile and apply it by double clicking but I think all above had the same effect, more or less..
    I would appreciate if you know how to solve this problem. (the O.S I tried is a Windows7 64bit)

    Thank you,
    -Murat

    • 09/12/2011 at 05:15 | #11

      Hi Murat,

      I can think of two possible explanations for the “error missing” problem
      - The Addin dll has not been correctly registered as a COM object
      - There’s a spelling error in the value of the addin registry key

      What I would try is to create an installer for the addin and install it like that on the other machine.
      There’s an easy installer option in VS, but in case you don’t have the correct VS package you could give wix a shot.
      I’ve written a tutorial on that here:
      http://geertbellekens.wordpress.com/2011/02/23/tutorial-deploy-your-enterprise-architect-csharp-add-in-with-an-msi-package/

      Geert

      • Murat Cinar
        13/12/2011 at 18:12 | #12

        Hi Geert,
        Thank you so much for your help. Right now, it is working perfectly with WIX installer.

        Murat.

  1. 31/01/2011 at 10:59 | #1
  2. 08/02/2011 at 05:01 | #2
  3. 15/02/2011 at 04:52 | #3
  4. 16/02/2011 at 02:55 | #4
  5. 23/02/2011 at 04:48 | #5
  6. 28/02/2011 at 08:13 | #6

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 129 other followers