Initialization code in your AutoCAD .NET application
It's very common to need to execute some code as your application modules are loaded, and then to clean-up as they get unloaded or as AutoCAD terminates. Managed AutoCAD applications can do this by implementing the Autodesk.AutoCAD.Runtime.IExtensionApplication interface, which require Initialize() and Terminate() methods.
During the Initialize() method, you will typically want to set system variables and perhaps call commands which execute some pre-existing initialization code for your application.
Here's some code showing how to implement this interface using VB.NET:
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports System
Public Class InitializationTest
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
<CommandMethod("TST")> _
Public Sub Test()
Dim ed As Editor = _
Application.DocumentManager.MdiActiveDocument.Editor
ed.WriteMessage("This is the TST command.")
End Sub
End Class
And here's the equivalent code in C#:
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using System;
public class InitializationTest
: 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...");
}
[CommandMethod("TST")]
public void Test()
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("This is the TST command.");
}
}
A few notes about this code:
.NET modules are not currently unloaded until AutoCAD terminates. While this is a popular request from developers (as it would make debugging much simpler), my understanding is that this is an issue that is inherent to the implementation of .NET - see this MSDN blog post for more information.
What this means is that by the time the Terminate() method is called, AutoCAD is already in the process of closing. This is why I've used Console.Write() rather than ed.WriteMessage(), as by this point there's no command-line to write to.
That said, you can and should use the Terminate() callback to close any open files, database connections etc.
Something else you might come across when implementing this... I've implemented a single command in this application for a couple of reasons: in my next post I'm going to segregate the command into a different class, to show how you can tweak your application architecture both to follow a more logical structure and to optimize load performance.
The second reason I added the command was to raise a subtle you might well hit while coding: you might see the initialization string sent to the command-line as the application loads, but then the command is not found when you enter "TST" at the command-line. If you experience this behaviour, you're probably hitting an issue that can come up when coding managed applications against AutoCAD 2007: there's been a change in this version so that acmgd.dll is loaded on startup, and under certain circumstances this assembly might end up getting loaded again if found on a different path, causing your commands not to work.
The issue can be tricky to identify but is one that can be resolved in a number of ways:
- Edit the Registry to disable the demand-loading "load on startup" of acmgd.dll (a bad idea, in my opinion - it's safer not to second guess what assumptions might have been made about the availability of core modules)
- Make sure AutoCAD is launched from its own working directory - commonly this issue is hit while debugging because Visual Studio doesn't automatically pick up the debugging application's working directory
- Set the "Copy Local" flag for acmgd.dll to "False". "Copy Local" tells Visual Studio whether the build process should make copies of the assemblies referenced by the project in its output folder
My preference is for the third approach, as on a number of occasions I've overwritten acmgd.dll and acdbmgd.dll with those from another AutoCAD version (inadvertently trashing my AutoCAD installation). This usually happens when testing projects across versions (projects that's I've set to output directly to AutoCAD's program folder, for convenience), and I've forgotten to change the assemblies references before building.
So I would actually set both your references to acdbmgd.dll and acmgd.dll to "Copy Local = False". You can do this either by selecting the Reference(s) via the Solution Explorer (in C#) or via the References tab in your Project Properties (in VB.NET) and then editing the reference's Properties.