create a DLL with AutoCAD.Net functionality to be used in AutoCAD VBA

create a DLL with AutoCAD.Net functionality to be used in AutoCAD VBA

Anonymous
Not applicable
5,617 Views
11 Replies
Message 1 of 12

create a DLL with AutoCAD.Net functionality to be used in AutoCAD VBA

Anonymous
Not applicable

I am trying to create a DLL which includes AutoCAD.Net functionality that is callable from VBA within AutoCAD.
To start off I created a simple DLL that contained no AutoCAD functionality that works by checking "Make assembly COM-visible" and "Register for COM interop".

I then created a DLL with some AUOCAD.Net functionality (CreateExtrudedSolid) but I get the following error
during the build:

 

Could not load file or assembly 'accoremgd, Version=23.0.0.0, Culture=neutral, PublicKeyToken=null'
or one of its dependencies. The system cannot find the file specified.

 

I am using Windows 10, .Net Framework 4.7.1, Visual Stuio 2017, AutoCAD 2019 and by class imports the following:

Autodesk.AutoCAD.ApplicationServices
Autodesk.AutoCAD.DatabaseServices
Autodesk.AutoCAD.Geometry
Autodesk.AutoCAD.Runtime

 

I have added the following references

accoremgd.dll
acdbmgd.dll
acmgd.dll
AcWindows.dll
Autodesk.AutoCADInterop.dll
Autodesk.AutoCADInterop.Common.dll

 

How do I make this work?

Thanks for your help.

0 Likes
Accepted solutions (2)
5,618 Views
11 Replies
Replies (11)
Message 2 of 12

TiStars
Advisor
Advisor

Excuse me , why you need it "callable from VBA"? I mean, you can run a dll directly without VBA


天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes
Message 3 of 12

TiStars
Advisor
Advisor

I just googled your error message then got these 2, hope they are helpful.

 

btw, I think the way you call it is unusual.

 

https://forums.autodesk.com/t5/net/could-not-load-file-or-assembly-accoremgd-dll-or-one-of-its/m-p/3...

 

https://stackoverflow.com/questions/39658086/could-not-load-file-or-assembly-accoremgd-version-20-0-...


天涯海角的山姆


您认为此帖子是否有用?欢迎为此帖点赞。

您的问题是否已得到解答?请点击“接受解答”按钮。


EESignature



0 Likes
Message 4 of 12

Anonymous
Not applicable

The reason that I want to call the DLL from VBA is so that I can integrate it into a larger, existing VBA application. The CreateExtrudedSolid function in AutoCAD.Net provides a very succinct way to create an extrusion between any two points.

 

I read your first link previously but took a closer look. The page and links did not lead to a solution.

 

I added the code in your second link to catch the AssemblyResolve event but the build fails so the code does not get a chance to run.

 

Thanks for your replies.

0 Likes
Message 5 of 12

norman.yuan
Mentor
Mentor

I tried with AutoCAD 2018 and VS2017 and do not think the result would be different for AutoCAD 2019. In my case, I do not get compiling error as you described. Here is what I did:

 

1. Create AutoCAD .NET Add-in DLL project, add references to AutoCAD .NET assemblies (accoremgd/acdbmgd/acmgd.dll)

2. Add public classes of business domain as needed in the project;

3. In the Project's "Properties" window page, make sure these:

a. "Application": I choose to target .NET4.7x (but .NET4.6x should be find for my Acad2018)

b. "Application": click "Assembly Information..." button, and select "Make assembly COM-Visible";

c. "Build": MAKE SURE to set "Platform target" to "x64" (since it is to be used as COM, it must be either 32, or 64 bit, not "Any CPU");

d. "Build": select "Register for COM interop";

 

Note, I run VS2017 as "Administrator", otherwise, after compiling, my regular user account is not allowed to register COM component.

 

Then, I do not have problem compile the DLL (and upon building completion, a COM class "[MyNetDll.MyClass]" is registered in Windows registry (I can find/browse it with RegEdt32.exe).

 

I do not have access to Acad2019. but I may verify it with my Acad2020 later, but I do not expect to see the building error as you described.

 

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 6 of 12

Anonymous
Not applicable

I tried your suggestions and still get the accoremgd.dll error. 

 

One thing you said got me thinking though ... I wonder if our IT department have implemented some kind of security measure to prevent me from registering the COM component (yes, I've reached the paranoia stage of trouble shooting).  They say that they have not but I am going to try this at home and see if it works.  I'll let you know how I make out tomorrow.

 

Thanks very much for your time.

0 Likes
Message 7 of 12

Anonymous
Not applicable

I tried your suggestions at home and the build still failed with the following message:

 

Could not load file or assembly 'accoremgd, Version=23.0.0.0, Culture=neutral, PublicKeyToken=null'
or one of its dependencies. The system cannot find the file specified.

 

Here is a summary of the steps I have taken and the results:

 

1.  start Visual Studio 2017 as administrator
2.  start a new Visual Basic class library project
3.  set project properties
4.  set target framework = .Net Framework 4.7.1
5.  Make assembly COM-Visible = check
6.  set Target CPU = x64
7.  Register for COM interop = check
8.  Start action = Start project
9.  References (all in C:\Program Files\Autodesk\AutoCAD 2019)
          accoremgd.dll
          acdbmgd.dll
          acmgd.dll
          AcWindows.dll
          Autodesk.AutoCAD.Interop.dll
          Autodesk.AutoCAD.Interop.Common.dll

10.  added code (see code below )

11.  in VS select build - build

12.  get error noted above

13.  the following files were created in "C:\custom\ccTools\ccTools\bin\x64\Debug"

          acmgd.dll

          ccTools.dll

          ccTools.pdb

          ccTools.xml

14.  nothing was added to the registry

15.  ccTools runs successfully in AutoCAD using NetLoad as the command line

 

code --------------------------------------------

 

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Runtime

 

Public Class SolidsCLS

 

<CommandMethod("Test123")>
Public Sub ExtrudeRegionTest()

 

    Dim pStartPoint As Point3d
    Dim pEndPoint As Point3d
    Dim pDiameter As Double

 

    pStartPoint = New Point3d(100, 200, 300)
    pEndPoint = New Point3d(200, 300, 400)
    pDiameter = 10

    CylinderExtrude(pStartPoint, pEndPoint, pDiameter)

 

End Sub

 

Public Function CylinderExtrude(
    ByVal iStartpoint As Point3d,
    ByVal iEndPoint As Point3d,
    ByVal iDiameter As Double
    ) As Solid3d

 

Dim pDirectionVector = New Vector3d(
    iEndPoint.X - iStartpoint.X,
    iEndPoint.Y - iStartpoint.Y,
    iEndPoint.Z - iStartpoint.Z
    )

 

Dim pCircle As New Circle(iStartpoint, pDirectionVector, iDiameter / 2)

 

Dim pDBObjColl As DBObjectCollection = New DBObjectCollection()
pDBObjColl.Add(pCircle)

 

Dim pRegionColl As DBObjectCollection = New DBObjectCollection()
pRegionColl = Autodesk.AutoCAD.DatabaseServices.Region.
    CreateFromCurves(pDBObjColl)

 

Dim pRegion As Region = pRegionColl(0)

 

Dim myTransMan As Autodesk.AutoCAD.ApplicationServices.TransactionManager
Dim myTrans As Transaction
Dim myDWG As Document
Dim myBT As BlockTable
Dim myBTR As BlockTableRecord

 

myDWG = Autodesk.AutoCAD.ApplicationServices.Application.
    DocumentManager.MdiActiveDocument
Dim myLock As DocumentLock
myLock = myDWG.LockDocument

 

myDWG = Autodesk.AutoCAD.ApplicationServices.Application.
    DocumentManager.MdiActiveDocument
myTransMan = myDWG.TransactionManager
myTrans = myTransMan.StartTransaction

 

myBT = myDWG.Database.BlockTableId.GetObject(OpenMode.ForRead)
myBTR = myBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)

 

Dim pSolid As Solid3d
pSolid = New Autodesk.AutoCAD.DatabaseServices.Solid3d
pSolid.RecordHistory = True

 

Dim DirectionVector = New Vector3d(
    iEndPoint.X - iStartpoint.X,
    iEndPoint.Y - iStartpoint.Y,
    iEndPoint.Z - iStartpoint.Z
    )


Dim mySweepOptions As New SweepOptions()
pSolid.CreateExtrudedSolid(pRegion, DirectionVector, mySweepOptions)
myBTR.AppendEntity(pSolid)
myTrans.AddNewlyCreatedDBObject(pSolid, True)

 

myTrans.Commit()
myTrans.Dispose()
myTransMan.Dispose()

 

Return pSolid
myLock.Dispose()
Autodesk.AutoCAD.ApplicationServices.Application.
    DocumentManager.MdiActiveDocument.Editor.Regen()

 

End Function

 

End Class

 

code --------------------------------------------

 

Thanks for your help so far and if you could take a look a look at this again I would very much appreciate it.

 

Fred

0 Likes
Message 8 of 12

norman.yuan
Mentor
Mentor
Accepted solution

OK, I repeated all the steps as you described, and indeed the build was failed with error. However, you failed provide the FULL ERROR message: it is NOT ONLY "Could not load file or assembly 'accoremdg,....', BUT ALSO the error message starts as"Cannot register assembly ".....\[theDll].dll".

 

Obviously, the DLL assembly can be compiled, but registering it as COM component fails because of certain functionality in accoremgd.dll cannot be used for COM exposure, namely, they are CommandClassAttribute and CommandMethodAttribute, at least. 

 

But think about it, if the COM DLL is to be used in VBA, there is no reason to have CommandClass/Method in it. The DLL should only contains classes with properties/methods that can be called by other COM-able code/VBA code. 

 

If you want to test your COM-able .NET DLL with CommandClass/Method, you should wrap up the CommandClass/Method in another separate project that reference this DLL project. This way, the DLL project can be used by both .NET add-in, or be exposed as COM-able.

 

HTH

Norman Yuan

Drive CAD With Code

EESignature

Message 9 of 12

Anonymous
Not applicable
Accepted solution

Thank you very, very, very much.  Removing the CommandMethod line fixed the problem.

 

Again, thanks.

 

Fred

Message 10 of 12

derrickw603S7WA
Explorer
Explorer

Hi all
I've just started on my .Net journey and I've been battling with the very same issue.
From my side, just want to say thank you very, very much too.
Derrick

0 Likes
Message 11 of 12

jklinkeB8EEG
Contributor
Contributor

I also am trying to add some functionality to an existing VBA application.  After I build my application, the JCK_VBA_Pipetools seems to be registered, but I'm unable to access the defined functions.  Does anyone know what I'm doing wrong? 

 

jklinkeB8EEG_0-1713289837678.png

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.Civil
Imports Autodesk.Civil.ApplicationServices

Public Class Class1
    Public Function getarea(x As Double, y As Double) As Double
        Return x * y
    End Function
    Public Function PipeHGL_HandleGet(HandEnt As String) As String ' This method can have any name
        PipeHGL_HandleGet = "No Pipe Exists"
        Try
            'Get Civil 3D application, document and database
            Dim CivDoc As CivilDocument = CivilApplication.ActiveDocument
            ' Dim JuncLoss = Us_HGMax - Us_HG
            Dim Doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            'MsgBox("Working Here:2")
            Using lock As DocumentLock = Doc.LockDocument
                Dim db As Database = Doc.Database
                Dim ed As Editor = Doc.Editor
                Dim MyPipe As DatabaseServices.Pipe = Nothing
                Dim MyStr As DatabaseServices.Structure = Nothing
                Dim tr As Transaction = Doc.TransactionManager.StartTransaction()
                Try

                    Dim ln As Long = Convert.ToInt64(HandEnt, 16)
                    Dim hn As Handle = New Handle(ln)
                    ' And attempt to get an ObjectId for the Handle
                    Dim id As ObjectId = db.GetObjectId(False, hn, 0)
                    Dim obj As DBObject = tr.GetObject(id, OpenMode.ForWrite)
                    Try
                        Dim xy(0 To 2) As Double
                        Dim oPipe As DatabaseServices.Pipe
                        If TypeOf obj Is DatabaseServices.Pipe Then
                            oPipe = obj
                            PipeHGL_HandleGet = oPipe.HydraulicGradeLineDown.ToString & ":" & oPipe.HydraulicGradeLineUp.ToString & ":" & (oPipe.HydraulicGradeLineUp + oPipe.JunctionLoss).ToString
                        End If
                        tr.Commit()
                    Catch ex As Autodesk.AutoCAD.Runtime.Exception
                        ed.WriteMessage(ex.Message)
                        'tr.Abort()
                        MsgBox("The Pipe With Handle: " & HandEnt.ToString & vbLf & "Was Not Found")
                    Finally
                        'tr.Dispose()
                    End Try
                Catch ex As Autodesk.AutoCAD.Runtime.Exception
                    ed.WriteMessage(ex.Message)
                    tr.Abort()
                    MsgBox("The Pipe With Handle: " & HandEnt.ToString & vbLf & "Was Not Found")
                Finally
                    tr.Dispose()
                End Try

            End Using
        Catch 'ex As Exception
            MsgBox("Something went wrong, you may want to audit your drawing and try again")
        Finally

        End Try

    End Function
End Class

   

0 Likes
Message 12 of 12

ActivistInvestor
Mentor
Mentor

Making your code accessible via COM requires a bit more than simply checking "Register for COM interop".

 

I would suggest you start here to learn the basics of the process, paying special attention to topic that introduces the [ClassInterface] attribute.

0 Likes