Introduction to VB.NET in AutoCAD®

by Will on November 18, 2010

VBA is in the process of being phased out, and the replacement is .NET. This may disappoint some of you that have VBA applications/skills, but you will be pleased to hear that you can still use code that you have, and all you know about VBA programming with AutoCAD® can still be put to good use using VB.NET. The following tutorial sets the foundation for creating your first VB.NET project, and should serve as a good starting point for migrating your code across to VB.NET.

What you need

There is no native IDE (integrated development environment) within AutoCAD® for developing .NET projects like you could with VBA (via the command VBAIDE). Instead, you need an external software development package for writing and compiling your code. Fear not however, you can download express editions of several programming suites for free directly from Microsoft’s website. Click here to visit the page for downloading Visual Basic Express 2010.
Next, you need to download the ObjectARX programming interface from AutoDesk’s website. Click here to visit the page for downloading ObjectARX. Ensure you acquire the correct version of the ObjectARX libraries for your version of AutoCAD®.

Create your first VB.NET AutoCAD® project

Open Microsoft Visual Basic Express, and select “New Project”, and then select the “Class Library” option. This creates a project that compiles to a dynamic link library (.dll file). In VBA you automatically have access to the AutoCAD® object, including objects such as ThisDrawing, but in this environment we have to create references to AutoCAD® explicitly ourselves. We do this by naming a reference to ObjectARX, which contains the AutoCAD® type libraries that we want to use.

  1. Under the Solution Explorer window, right click on your project (ClassLibrary1 if you haven’t renamed it), and select Properties.
  2. Click on the References Tab.
  3. Click on the Add dropdown, and select Reference.
  4. Click on the Browse Tab, and navigate to where the ObjectARX libraries are installed. Typically this will be C:\ObjectARX 2011\
  5. Depending on your preference, open the folder inc-win32 or inc-x64.
  6. Select the dll files Autodesk.AutoCAD®.Interop.dll and Autodesk.AutoCAD®.Interop.Common.dll, and click OK. This imports the AutoCAD® type libraries.
  7. Add another reference, and this time select the inc folder. Select AcMgd.dll and AcDbMgd.dll, and click OK. I’m not completely sure why these are required, but apparently they are!
  8. Finally, you’ll notice on the References Tab that the Copy Local property of the AcMgd.dll and AcDbMgd.dll references is set to True. This needs to be False so select them, and under the properties window change the Copy Local property to False.

Writing some initial code

Our project is now set up with all the references required to link to AutoCAD®. Now we can begin writing code.
Switch back to code view (If you haven’t renamed anything, double click on Class1.vb under Solution Explorer). We need to specify in this class which libraries from our references we intend to use, so right at the top of the class (before Public Class Class1) put the following code:

    'Contains the AutoCAD® Type Library
    Imports Autodesk.AutoCAD®.Interop
    'Contains the AutoCAD®/ObjectDBX Type Library
    Imports Autodesk.AutoCAD®.Interop.Common

Now in VBA, we had access to the ThisDrawing object. This is quite useful, so it would be useful to have the same functionality here. Now that we have access to the AutoCAD® object model, we can add a simple Get procedure to retrieve the object we want. Put the following code inside the Class (between Public Class Class1 and End Class):


    Public ReadOnly Property ThisDrawing As AcadDocument
        Get
            Return Autodesk.AutoCAD®.ApplicationServices.Application.DocumentManager.MdiActiveDocument.AcadDocument
        End Get
    End Property

Now we can use ThisDrawing anywhere within the class as we could in VBA.

Writing our first AutoCAD® Function

Everything is in place now to start producing our own AutoCAD® commands. If you have any VBA code you want to transfer across, you should now be able to paste them into this class. Here’s one that I wrote recently as an example. The code adds a border to MTEXT, and the only difference between this code and VBA code is that I’ve made use of the .NET Try/Catch statement, which is better for error trapping than previous methods in VBA:

    Public Sub CreateMTextBorder()
        Dim ent As AcadEntity
        Dim pnt As Object
        Try
            ThisDrawing.Utility.GetEntity(ent, pnt, "Pick MTEXT to add a border to")
            Dim mt As AcadMText
            mt = ent
            Dim Min As Object, Max As Object
            Dim Coords(7) As Double
            mt.GetBoundingBox(Min, Max)
            Coords(0) = Min(0) - 1
            Coords(1) = Min(1) - 1
            Coords(2) = Max(0) + 1
            Coords(3) = Min(1) - 1
            Coords(4) = Max(0) + 1
            Coords(5) = Max(1) + 1
            Coords(6) = Min(0) - 1
            Coords(7) = Max(1) + 1
            If ThisDrawing.ActiveSpace = AcActiveSpace.acModelSpace Then
                ThisDrawing.ModelSpace.AddLightWeightPolyline(Coords).Closed = True
            Else
                ThisDrawing.PaperSpace.AddLightWeightPolyline(Coords).Closed = True
            End If
        Catch
            ThisDrawing.Utility.Prompt("Invalid Selection")
        End Try
    End Sub

Make sure that your subroutine is declared Public as opposed to Private, so that it will be visible by AutoCAD®. Also, there is one final piece of code we need to add to make this visible by AutoCAD®. We need to add some META data before the subroutine, which tells AutoCAD® that the subroutine is callable directly from AutoCAD®. This is where we assign our subroutine a Command Name for our AutoCAD® Command Line. Add the following code on the line before Public Sub CreateMTextBorder():

	<Autodesk.AutoCAD®.Runtime.CommandMethod("MTEXTB")> _

Whatever we put in the brackets will be the command that we type into the AutoCAD® command line.

Our class is now complete, and is ready to be compiled into a DLL file for use with AutoCAD®.

Compiling

Under the debug menu, we can select Build to create our .dll, but if we do it now the NETLOAD command in AutoCAD® will fail to load the .dll file. This is because the .dll file must be built on the same version of the .NET framework as the version of AutoCAD® you are using. AutoCAD® 2011 is built on version 3.5 of the .NET framework, so we need to tell VB to compile our class using this version.

  1. Go to project properties as we did before for adding references.
  2. Click on the Compile Tab.
  3. At the bottom, click on Advanced Compile Options.
  4. At the bottom of the Advance Compiler Settings dialog box, select the Target Framework .NET Framework 3.5.
  5. Click OK. This usually requires closing and reopening the project afterwards.

Now we can build our .dll file based on the same .NET Framework as AutoCAD®, which should make it compatable. It is useful to have the Output Window open, so that we can grab the location of the compiled .dll file once the build is complete. You can open this window by going Debug > Windows > Output. Go Debug > Build, and this will compile the .dll file. Copy the path of the .dll file from the Output window, and open AutoCAD®.

Type NETLOAD into the command line. This is the command for loading .NET projects. You will be prompted to supply a path, so paste in the path to the .dll file we just created. If it worked, it should silently finish the command, i.e., you shouldn’t get any error messages. Now that the .dll is loaded you should be able to type in the command specified in the META data to call the subroutine inside the .dll, in the case if this example, MTEXTB.


I would like to take this opporunity to suggest that you subscribe to my blog – if you work with AutoCAD® I have many tips and tricks on the tip of my tongue. I guaranteee that you will find it a valuable resource.

Enter Your Mail Address

Be Sociable, Share!

{ 29 comments… read them below or add one }

Paolo December 11, 2010 at 4:41 pm

I Will;
I’m an italian developer and I developed an application in autocad vba that allows you to make plans for a loft in carpentry with the automatic generation of 2D objects.
Now I have to migrate the project in vb.net. Your knowledge and your information will be invaluable to me

Thank you.

Reply

Will December 13, 2010 at 8:07 am

No problem Paolo. If you have any specific problems please don’t hesitate to ask.

Will

Reply

Mike Wohletz January 12, 2011 at 11:09 pm

Will
I have never seen the mix of COM and straight managed code before, although I was skeptical of this working I had to give it a try and found that it does work quite well. Do you know if this is built using the ObjectARX2011 library if it will work with AutoCAD 2010 or is it going to be version specific going this route? I currently use all managed code and it works fine from 2009 to current releases, but some things can be handled easier using the COM way vs the long code required for managed code.

Reply

Will January 13, 2011 at 9:41 am

I believe it has to be version specific using this route, which is a disadvantage unfortunately. Nonetheless I think this is a very good way to get started.

Reply

svplaser September 10, 2012 at 6:29 am

Hi,

What is the difference between COM API and .NET API of autoCAD?

I thought we need to strictly use the transaction manager and add/delete entities from Autocad’s model space.
But the example in this link is not using “transaction” manager and this is still working.
http://howtoautocad.com/introduction-to-vb-net-in-autocad/
From the comments I learnt that this is using COM API instead of .NET API.

But I cant find any detail about this COM API.
What exactly is this COM API? Will it work with all versions of autocad?

regards

Reply

Will October 2, 2012 at 11:36 am

COM stands for Component Object Model, and simply put its an interface for interacting with an object, such as the AutoCAD Application. Third party applications can create a reference to AutoCAD, and call methods exposed through this COM interface, which we can use to manipulate AutoCAD.

However, this is not the best way. It is much better to work with managed code, using transactions, even though it is more difficult to (initially) get your head around. So have a dig around on my site – I believe there is a post which explains how to create managed code.

Will

Reply

Mike Wohletz January 13, 2011 at 2:31 pm

I guess that if you wanted to do this using previous knowledge of VBA as COM you could create functions that are late binding. in my example I have created a project as you have shown except that I am not going to add the command method as that is actually part of the managed code, add the references and for each version and then build. For this example the two .DLL files are going to be placed on the root of c:\.
I will have an AutoCAD2011COM.dll and AutoCAD2010COM.dll with the following code:
The only difference in the two will be the reference files
Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.Interop

Public Class Class1
Public Shared ReadOnly Property ThisDrawing() As AcadDocument
Get
Return Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.AcadDocument
End Get
End Property
Public Shared Function GetBlockCount() As Integer
Return ThisDrawing.ActiveLayout.Block.Count

End Function
End Class

I will then build a managed Add-In for AutoCAD; this will not contain the Autodesk.AutoCAD.Interop.dll and Autodesk.AutoCAD.Interop.Common.dll as they are only used for COM applications. It will have the AcMgd.dll and AcDbMgd.dll referenced as they are used for managed code and the 2011 version will work for AutoCAD 2011, 2010, and 2009, the code in that class will look like this.
Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.Runtime

Public Class Class1
Public Sub entcount()
If ApplicationServices.Application.Version.ToString.Contains(“18.1″) Then
‘ will will say that this is AutoCAD 2011
Dim RA As Reflection.Assembly = Reflection.Assembly.LoadFile(“C\AutoCAD2011COM.dll”)
Dim obj As Object = RA.CreateInstance(“AutoCAD2011COM.Class1″, True)
MsgBox(obj.GetBlockCount())
obj = Nothing
End If

If ApplicationServices.Application.Version.ToString.Contains(“18.0″) Then
‘ will will say that this is AutoCAD 2010
Dim RA As Reflection.Assembly = Reflection.Assembly.LoadFile(“C:\AutoCAD2010COM.dll”)
Dim obj As Object = RA.CreateInstance(“AutoCAD2010COM.Class1″, True)
MsgBox(obj.GetBlockCount())
obj = Nothing
End If

End Sub

End Class
The end result of this example is the count of entities in the active layout.

Reply

Ronanry March 14, 2011 at 8:04 pm

Guys !! i’ve only thing to say : I LO-VE YOU !!!!!!!
Since 2 weekends i’m seeking documentation on using vb.net and acad and nothing even works correctly
One “copy paste” from your code and it works fine …directly !!!

(just one thing….in the “compiling” part, you should explain that project has to been saved before changing framework) <== one other thing, you're the only one explaining how to work with both framework "correctly"
Really really thank you !!

Reply

Pfillion August 19, 2011 at 6:42 pm

Hello,

I am writting a .net program, and a part of it, I made a dll that run the matrix3d.wordtoplane method. Now, I have to do netload into autocad. How can I run the method I created in my dll from my vb.net program?

Thanks

Reply

Will August 25, 2011 at 8:07 pm

Subroutines can be prefixed with this:

replacing COMMAND_NAME_HERE with the command you want to use in AutoCAD. So, whenever you use the command in AutoCAD it will call this subroutine.

Hope this helps!
Will

Reply

Simon September 6, 2011 at 2:36 pm

Will
I am trying to print CAD drawings from VB.net will the ObjectARX contain the dlls to be able to do this and where is the best place to find the methods and examples, any help appreciated
Regards
Simon

Reply

Will September 7, 2011 at 7:39 am

Yes, it should be possible. Autodesk provide a set of documentation for the ObjectARX libraries, and that should be your first place to look. I also find it quite helpful simply googling what you’re trying to achieve, as usually someone has already done the work for you, and you can reverse-engineer their code.

Reply

Clayton November 25, 2011 at 12:30 am

Does this work for AutoCAD 2009 (or more specifically AutoDesk Mechanical Desktop 2009)? If so what ObjectARX do I download?

Reply

Will November 30, 2011 at 10:25 am

It should work with 2009. You just need to download the ObjectARX libraries for your version, which should be listed on Autodesk’s website.

Reply

Michael February 9, 2012 at 5:36 pm

That property statement to add “ThisDrawing” is great for migrating VBA code to VB.NET. However I am curious, what would be the VB.NET way to access those properties and methods without using “ThisDrawing”? For example, how would you write this code in VB.NET without using “ThisDrawing”?

ThisDrawing.Utility.Prompt(“Invalid Selection”)

Thanks!

Reply

Alan Chant March 2, 2012 at 10:25 am

Hi Will
I am just starting out with some VB.NET programming for AutoCAD and I am trying to find a resource that lists all the AutoCAD classes along with their methods and properties.

Do you know if such a resource exists?

Thanks
Alan

Reply

acadman March 9, 2012 at 9:36 am

hi Will,
thx for ur great code. I m now working on a new project. I m using a data base on excel to generate plan by autocad. All the code is on VBA excel and it do the job. The user will execute only the code by click on a button on excel and the code do all the job. the problem is when i close autocad and if i execute second time the code crash. the solution i m using now is to click on stop on the vba compiler. could u help to find the solution because users of my application don’t know about how to use vba.

Reply

John March 28, 2012 at 12:47 pm

Will VB.net work on an OEM version of AutoCAD 2012?

Reply

Shirley May 15, 2012 at 10:55 pm

Hi Will,

I am a developer, trying to trap the plot event (in AutoCAD 2012) so that when our users click on print/batch plot, a dialog box will display and prompt them to enter data (account to charge the plotting to, etc.). In VS2010, I have a startup project, already has properties/debug / start external program set to acad.exe. In the VS2010 startup project, I have specified [assembly : CommandClass and ExtensionApplication] both pointing to the proper namespace.classname. The breakpoint at the Initialize() event was never hit. I am not familiar with AutoCAD 2012. I would really appreciate it if you would be so kind to point me to the right direction? Your blog mentioned “using AutoCAD 2012 with .NET 3.5 and not .NET 4.0″ already helped me. Thanks.
Sincerely,
Shirley

Reply

Will August 8, 2012 at 6:48 pm

I believe this might be achievable by trapping the event that fires when a new command is invoked. Then you should be able to filter out everything that isn’t a “PLOT” command and do as you need.

Reply

hamid May 19, 2012 at 9:30 pm

hi
i want to write a program like autocad which it has some icon for draw and icons become in left hand,and user can drag those,and after drag icon by right click it has access data
please help me

Reply

Will August 8, 2012 at 6:46 pm

Try looking into VB.NET forms – there are many ways to draw graphics onto forms that will be of use such as the Graphics object.

Reply

nazanin June 1, 2012 at 12:32 pm

i am going to start vb programming in autocad , would you please introduce me some good ebook references or weblogs in this category?

Reply

Will August 8, 2012 at 6:44 pm

I will be creating an online course shortly – watch this space!

Reply

Mojaba April 17, 2013 at 5:53 am

I am in the same boat. Would you please share any useful resources with me as well?

Reply

Dave Gleason January 10, 2013 at 8:50 pm

Paolo,

I’m wondering. Can you create a standalone exe that uses acad.dlls to create a simplified version of AutoCad as a whole. We are looking to create a simple cad tool that does rudimentary editing, layering of 2d data (polylines I suppose) for our printing system. We’ve been using AutoCad with a VBA project to do this, but we really don’t need the sophistcation or expense of AutoCad. The key elements that we use are fillet, offset and trim methods then I added the code to export the dxf to our motion controller language.

Alternatively I am learning how to write a plug-in for 2013. But it just seems like there is a more elegant way to do this for our needs that doesn’t include th 4K for autocad. The thing that has kept us tied it the accessablilty to AutoCad from VBA or .net.

Thank you for your thoughts.
Dave Gleason

Reply

Will January 11, 2013 at 1:13 pm

Hi Dave,

Even if you could create such a standalone .exe, it would rely upon components that exist in AutoCAD, and therefore the standalone would only work on machines that have AutoCAD installed, which I guess would defy the purpose of it.

Good idea though!

Regards,
Will

Reply

Moji April 17, 2013 at 5:41 am

Hi Will,

As a newbie, I followed the same steps you described above. I have Acad 2014 installed and using VS2012 as my IDE.
Just before writing any code, I face some difficulties introducing “ThisDrawing” to VS2012. Here is the error I get:
———————
Error 1 Reference required to assembly ‘accoremgd, Version=19.1.0.0, Culture=neutral, PublicKeyToken=null’ containing the base class ‘Autodesk.AutoCAD.ApplicationServices.Core.Application’.
———————
All of four DLLs you mentioned earlier in your tutorial, have been referenced in my project properties.

I was wondering if you could help me.

Regards
Moji

Reply

Will April 28, 2013 at 9:42 am

Hi Moji,

In AutoCAD 2013 and later, you’ll need to add a reference to “accoremgd” as well. That should solve the problem.

Regards,
Will

Reply

Leave a Comment

{ 1 trackback }

Previous post:

Next post: