Kean Walmsley

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Twitter Updates

    follow me on Twitter



    « Initialization code in your AutoCAD .NET application | Main | Automatic loading of .NET modules »

    September 08, 2006

    Optimizing the loading of AutoCAD .NET applications

    In my previous post I described how you could use the Autodesk.AutoCAD.Runtime.IExtensionApplication interface to implement initialization code in your .NET module. Building on this, we're now going to look at how use of the Autodesk.AutoCAD.Runtime.IExtensionApplication interface can also allow you - with very little effort - to optimize the architecture of your managed modules for faster loading into AutoCAD.

    First some information from the "Using .NET for AutoCAD documentation" (which is available in the ObjectARX Developer's Guide on the ObjectARX SDK):

    When AutoCAD loads a managed application, it queries the application's assembly for an ExtensionApplication custom attribute. If this attribute is found, AutoCAD sets the attribute's associated type as the application's entry point. If no such attribute is found, AutoCAD searches all exported types for an IExtensionApplication implementation. If no implementation is found, AutoCAD simply skips the application-specific initialization step.

    ...

    In addition to searching for an IExtensionApplication implementation, AutoCAD queries the application's assembly for one or more CommandClass attributes. If instances of this attribute are found, AutoCAD searches only their associated types for command methods. Otherwise, it searches all exported types.

    The samples that I've shown in this blog - and most of those on the ObjectARX SDK - do not show how you can use the ExtensionApplication or CommandClass attribute in your code, as it's not essential to implement them for your application to work. But if you have a large .NET module to be loaded into AutoCAD, it might take some time for AutoCAD to check the various objects in the assembly, to find out which is the ExtensionApplication and which are the various CommandClasses.

    The attributes you need to implement are very straightforward:

    C#:

    [assembly: ExtensionApplication(typeof(InitClass))]

    [assembly: CommandClass(typeof(CmdClass))]

    VB.NET:

    <Assembly: ExtensionApplication(GetType(InitClass))>

    <Assembly: CommandClass(GetType(CmdClass))>

    These assembly-level attributes simply tell AutoCAD where to look for the various objects it will otherwise need to identify by searching. Here's some more information from the documentation on the use of these attributes:

    The ExtensionApplication attribute can be attached to only one type. The type to which it is attached must implement the IExtensionApplication interface.

    ...

    A CommandClass attribute may be declared for any type that defines AutoCAD command handlers. If an application uses the CommandClass attribute, it must declare an instance of this attribute for every type that contains an AutoCAD command handler method.

    While optimizing yesterday's code to reduce load-time, I also changed the structure slightly to be more logical. The above attributes also take classes within a namespace, so I decided to split the initialization code (the "Initialization" class) away from the command implementations (the "Commands" class), but keeping them both in the same ("ManagedApplication") namespace.

    And here's the code...

    C#:

    using Autodesk.AutoCAD.Runtime;

    using Autodesk.AutoCAD.ApplicationServices;

    using Autodesk.AutoCAD.EditorInput;

    using System;

    [assembly:

      ExtensionApplication(

        typeof(ManagedApplication.Initialization)

      )

    ]

    [assembly:

      CommandClass(

        typeof(ManagedApplication.Commands)

      )

    ]

    namespace ManagedApplication

    {

      public class Initialization

        : Autodesk.AutoCAD.Runtime.IExtensionApplication

      {

        public void Initialize()

        {

          Editor ed =

            Application.DocumentManager.MdiActiveDocument.Editor;

          ed.WriteMessage("Initializing - do something useful.");

        }

        public void Terminate()

        {

          Console.WriteLine("Cleaning up...");

        }

      }

      public class Commands

      {

        [CommandMethod("TST")]

        public void Test()

        {

          Editor ed =

            Application.DocumentManager.MdiActiveDocument.Editor;

          ed.WriteMessage("This is the TST command.");

        }

      }

    }

    VB.NET:

    Imports Autodesk.AutoCAD.Runtime

    Imports Autodesk.AutoCAD.ApplicationServices

    Imports Autodesk.AutoCAD.EditorInput

    Imports System

    <Assembly: _

      ExtensionApplication( _

        GetType(ManagedApplication.Initialization))>

    <Assembly: _

      CommandClass( _

        GetType(ManagedApplication.Commands))>

    Namespace ManagedApplication

      Public Class Initialization

        Implements Autodesk.AutoCAD.Runtime.IExtensionApplication

        Public Sub Initialize() Implements _

        IExtensionApplication.Initialize

          Dim ed As Editor = _

            Application.DocumentManager.MdiActiveDocument.Editor

          ed.WriteMessage("Initializing - do something useful.")

        End Sub

        Public Sub Terminate() Implements _

        IExtensionApplication.Terminate

          Console.WriteLine("Cleaning up...")

        End Sub

      End Class

      Public Class Commands

        <CommandMethod("TST")> _

        Public Sub Test()

          Dim ed As Editor = _

            Application.DocumentManager.MdiActiveDocument.Editor

          ed.WriteMessage("This is the TST command.")

        End Sub

      End Class

    End Namespace

    TrackBack

    TrackBack URL for this entry:
    http://www.typepad.com/services/trackback/6a00d83452464869e200d834b062e453ef

    Listed below are links to weblogs that reference Optimizing the loading of AutoCAD .NET applications:

    Comments

    Kean,

    You're going to have to start charging us for this resource. :) Thanks again! It's admirable that you're so generous with your time and knowledge.

    Hopefully you're putting a book together. ~Hint Hint~

    Cheers,
    Paul

    Hi Paul,

    Thanks for your encouraging words. But I'd recommend against putting ideas like that (the one about charging) into my head :-).

    I intend this to continue as a free resource for developers working with Autodesk technologies... if people want to pay to get more information like this, they should join ADN (if they haven't already, of course), as that's the source of much of this knowledge.

    As for my time - I hope to continue posting as frequently as I have, but my wife is expecting our second child any day now. I anticipate it soon becoming difficult to spend the few hours that I do each week on this blog, at least for a while.

    Maybe one day I'll write a book, but I suspect it'll be about something other than programming (you never know, though). Blogs are such a great way for getting technical information out there quickly without the editorial/publishing process making it stale... and the non-linearity of the medium suits my whimsical nature. :-)

    Regards,

    Kean

    Hey Kean,

    Congrats to you and your family on the new addition.

    Cheers,
    Paul

    i seem to be missing a key part. I keep getting an error the command doesn't exist. did i miss a step on registering the command? the code compiles as correct, is there a step to insert somewhere?

    I have no way of knowing what isn't working... you can use tools such as FileMon and RegMon to monitor what is happening on your system (when the Registry gets accessed or when a file is loaded from disk). They're available at the Windows Sysinternals website.

    Kean

    Kean

    I am missing the part where AutoCAD loads the code. I am trying to load it when AutoCAD 2009 starts. Do I make this code a WPF Class Library and then I need to add the dll to AutoCAD netload somewhere?

    Thanks,

    Paul

    Forgot to say I am writing in C#.

    Paul

    Nevermind...I find the link to the solution....you answered my questions before I answered it haha

    http://through-the-interface.typepad.com/through_the_interface/2006/09/automatic_loadi.html

    In the ObjectArx 2010 documentation for the CommandClassAttribute it says:

    This custom attribute class is used to mark a type as the application's command class. An application may designate one, and only one, type as its command class. AutoCAD looks for an application's command methods on the type that bears this attribute.

    Above, it sounds like it could be defined on multiple types. Is this accurate?

    I agree that previously the documentation implied it was possible. Have you tried it?

    Kean

    I can define multiple classes with the [assembly: CommandClass(typeof(...))] attribute. Commands in both classes are recognized in AutoCAD 2010

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search