Introduction to VB.NET in AutoCAD®

William Forty
William Forty

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.


Comments

Paolo
2010-12-11 16:41:36

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.

Will
2010-12-13 08:07:27

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

Will

Mike Wohletz
2011-01-12 23:09:13

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.

Will
2011-01-13 09:41:26

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.

svplaser
2012-09-10 06:29:11

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. 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

Will
2012-10-02 11:36:39

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

Mike Wohletz
2011-01-13 14:31:48

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.

Ronanry
2011-03-14 20:04:02

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 !!

Pfillion
2011-08-19 18:42:11

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

Will
2011-08-25 20:07:02

Subroutines can be prefixed with this:

<CommandMethod("COMMAND_NAME_HERE")>

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

Simon
2011-09-06 14:36:22

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

Will
2011-09-07 07:39:39

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.

Clayton
2011-11-25 00:30:39

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

Will
2011-11-30 10:25:50

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

Michael
2012-02-09 17:36:26

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!

Alan Chant
2012-03-02 10:25:43

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

acadman
2012-03-09 09:36:03

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.

John
2012-03-28 12:47:42

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

Shirley
2012-05-15 22:55:59

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

Will
2012-08-08 18:48:37

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.

hamid
2012-05-19 21:30:59

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

Will
2012-08-08 18:46:54

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.

nazanin
2012-06-01 12:32:55

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

Mojaba
2013-04-17 05:53:36

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

Will
2012-08-08 18:44:56

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

parsa
2016-01-26 06:52:28

hello sry i have problem in autocad runtime erorr plz send your email to me to can send picure of that erorr i want to resolve this becuse i cant working

Hassan Abdel
2012-11-28 09:58:08

I got the following "error message" when I was trying to compile the above vb.NET code.

A project with an Output Type of Class Library cannot be started directly. In order to debug this project, add an executable project to this solution which references the library project. Set the executable project as the startup project.

What should I do to solve this error? Thank you

Dave Gleason
2013-01-10 20:50:29

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

Will
2013-01-11 13:13:42

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

Shukla
2013-03-19 06:08:50

Hello, I want to load my dll file without using netload command..means i want my dll file to be loaded at the starting of AutoCAD®.. How to do it? I have tried some registry changes but it didn't work [HKEY_CURRENT_USER\Software\Autodesk\AutoCAD®\R17.0\ACAD-5001:409\Applications\MyTestApplication]

"DESCRIPTION"=" DemoApp"

"LOADCTRLS"=dword:00000002

"MANAGED"=dword:00000001

"LOADER"="C:\My Path\DemoApp"

I am using AutoCAD® 2010 mechanical .

shukla
2013-03-19 06:10:04

Hello, I want to load my dll file without using netload command..means i want my dll file to be loaded at the starting of AutoCAD®.. How to do it? I have tried some registry changes but it didn’t work [HKEY_CURRENT_USER\Software\Autodesk\AutoCAD®\R17.0\ACAD-5001:409\Applications\MyTestApplication]

“DESCRIPTION”=” DemoApp”

“LOADCTRLS”=dword:00000002

“MANAGED”=dword:00000001

“LOADER”=”C:\My Path\DemoApp.dll”

I am using AutoCAD® 2010 mechanical

Moji
2013-04-17 05:41:22

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

Will
2013-04-28 09:42:44

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

Dhimant Patel
2013-08-14 17:14:47

Hi,

Right now I am working in autocad customization. .

I just want to know that what is the basic difference between COM API & NET API.... it means which features are there which are available in COM API but not in BET API or vice versa...

And if possible tell the pros & cons of both the APIs...

Thanks In Advance. ....

Brian
2014-10-29 18:40:06

Hello I have a vba file i use in cad2006 vba is launched using a LISP - works well in 2006. Now moving to cad2013. When i initiate the vba (enabler installed) - utility starts to run correct but eventually errors "Execution error" is there a way to debug this or would it be easier to move code to .net

Will
2014-11-21 07:16:37

If you get an error, which then shows you the line of code in VBA, you're probably better off debugging from there, because you can see the state of the program and check what has gone wrong in the context of the running code.

ykrao
2015-07-19 11:23:34

very nice to see the valuable information i am an auto cad user for about 15 years of different applications like for GIS and structural drawings, since i got bored as production guy i want to switch to some development side since i have done graduation in computer applications learnt so many software but still i could switch to the software side, with autocad experience and other software knowledge like dot net, oracle how to quick start my switch-over please guide me.

your advice and guidance in in ned

thanks with regards

ykrao

Raffaele
2015-09-13 20:50:08

I would like to visualize in a palette a value of a parameter of an object selectioning it. I mean better. If I have a paralellepiped (something made with line in the verticec) and i select it in autocad i want to visualize the length of the vertical line; so if i change this value i would like to see the object modified in the autocad model.

Could you help me please.

hassan sharafi
2016-03-17 13:58:48

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®

hassan sharafi
2016-03-17 15:32:27

"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® " I cant find path of the .dll file :( plz help me :(