Preventing a .NET module from being loaded by AutoCAD

This is an interesting one that came up recently during an internal discussion:

During my module's Initialize() function, I want to decide that the module should not actually be loaded. How can I accomplish that?

The answer is surprisingly simple: if you throw an exception during the function, AutoCAD's NETLOAD mechanism will stop loading the application.

For an example, see this C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

namespace PreventLoad

{

  public class Commands

  : IExtensionApplication

  {

    public void Initialize()

    {

      // This will prevent the application from loading

      throw new Exception();

    }

    public void Terminate(){}

    [CommandMethod("TEST")]

    static public void TestCommand()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      doc.Editor.WriteMessage(

        "\nThis should not get called."

      );

    }

  }

}

Here's what happens when we attempt to load the application and then run the TEST command:

Command: FILEDIA

Enter new value for FILEDIA <1>: 0

Command: NETLOAD

Assembly file name: c:\MyApplication.dll

Command: TEST

Unknown command "TEST".  Press F1 for help.

13 responses to “Preventing a .NET module from being loaded by AutoCAD”

  1. That's a useful tip, thanks Kean.

    One thing though - have you travelled forward in time by a couple of days?

    My browser is saying this was posted on the 12th and yet today is only the 8th..

    ๐Ÿ™‚

  2. OK, time to come clean: time travel ended up being the only way for me to keep up with my blog posting schedule. ๐Ÿ™‚

    Joking aside - I had been planning to post this on the 12th (I tagged it in TypePad to publish then), but I then decided to promote it by a few days and publish it today.

    So this must be a quirk of TypePad - I'll see if I can edit the post to fix it.

    Thanks, Alex!

    Kean

  3. Kean,

    So if we extrapolate from your post, we can come up with a scenario that uses a decision branch that will tell the .NET module to finish loading or not. In plain and simple terms so that I can really understand this, if some condition is not met, then stop.

    My question is this, is there a way (I've tried the conventional way to no avail) to load that module if the condition is then satisfied?

    For example, if we NETLOAD the module and Initialize function sees that the OSMODE is set to something other than 0, 383 for instance, we tell the user that the value of OSMODE must be 0 in order to load the module. So the user sets OSMODE to 0 and tries to NETLOAD the module again. What I keep seeing is that nothing happens. NETLOAD already thinks the module is loaded in its entirety even though it really wasn't because of the Throw. Is there a way around that? Does this even make sense?

  4. John,

    I didn't put the condition in there explicitly, but that was my point. You wouldn't always stop it from loading (that would be pretty pointless :-).

    I see what you mean about the module no longer being loadable in that session. I'll check on whether it's possible to subsequently load without restarting AutoCAD.

    Kean

  5. Kean.
    I have another .NET loading question for you.

    Is there a .NET equivalent of the ObjectARX AcadAppInfo class that allows you to easily manipulate the demand loading registry keys?

    I had a quick search on the ADN and couldn't find anything obvious but I thought I'd ask you before embarking on cloning the AcadAppInfo functionality myself!

    Obviously if there is an ADN solution just let me know and I'll add the issue in DevHelpOnline ๐Ÿ™‚

    Chris

  6. Chris,

    I don't know - I haven't used one, myself.

    I suggest posting your question through DevHelp Online. ๐Ÿ™‚

    Will I see you at AU, this year?

    Kean

  7. John,

    It turns out it's the .NET loader that stops the module from being loaded on subsequent attempts - we have no control over this.

    So it appears this is a reasonable mechanism to implement some kind of security feature, i.e. "only allow my module to be loaded if this is a legal installation of my software", rather than preventing load under certain configuration options (where it would be better to temporarily disable your application's functionality or - with the user's permission - change the problematic config options in AutoCAD).

    Regards,

    Kean

  8. Hi Kean.

    I suppose this is one of those perception things. By the time the Initialize() method of an IExtensionApplication is called, the module/assembly that houses it has already been loaded, and can't be unloaded.

    Throwing the exception in Initialize() only prevents the loader from defining commands, and that's about it.

    Also, the fact that you see no message whatsoever when you throw the exception, is actually a bug. AutoCAD is supposed to display the exception stack trace when that happens (and did in earlier releases, but in AutoCAD 2007 or later it doesn't).

    That has been a constant source of frustration for myself and many others because when commands do not work, it is almost always because an exception is being thrown by code called from Initialize(), and the loader is supressing the error message and as a result, the only way the programmer can find out it happens is to run the app in the debugger.

    My standard advice is to wrap the entire Initialize() method's body in a try/catch block, and if an exception is thrown, you can display a message yourself from the catch block.

  9. "Is there a .NET equivalent of the ObjectARX AcadAppInfo class that allows you to easily manipulate the demand loading registry keys?"

    In the file at the link below, you will find a class called ExtensionApplicationInfo.
    caddzone.com/Ext...

  10. Tony you're a star, that looks like just the ticket, thanks very much ๐Ÿ˜€

    Kean, as much as I'd love to attend AU08 is looking doubtful, I've got an application to release by the end of the year and going to AU will remind me of all the cool stuff I don't have time to implement! I've already learned my lesson and re-scheduled Q4 2009 to make sure I have time to come next year though!

    I'll do my best to be at the London DevDay, are you attending the "tour"? Maybe I'll catch up with you there?

    Chris

  11. I'll certainly be in Paris, but haven't thought much about the other dates, as yet.

    Kean

  12. Thank you so much. But I also need to display error message "dll is incompatible with this version of AutoCAD." in command prompt.

    Please guide me

    1. I'm afraid I don't have time to provide support. Please post your question on the Autodesk forums.

      Kean

Leave a Reply

Your email address will not be published. Required fields are marked *