.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Vb.net & Autocad: Exception from HRESULT: 0x8007007E

16 REPLIES 16
Reply
Message 1 of 17
cokhitp
1589 Views, 16 Replies

Vb.net & Autocad: Exception from HRESULT: 0x8007007E

Hello to everybody.

 

I have tried to write a code that can update attribute data in block of autocad file.

 

I found alot of example in this forum, but i dont know why my programe can not work.

 

My PC is winXP, VS2008, autocad2009.

 

1. This code is work ofcouse:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MsgBox("hello")
    End Sub

 

2. But this one does not work:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MsgBox("hello")
        Dim myBT As DatabaseServices.BlockTable    
    End Sub

 

As long as i insert in the code which relative to reference .dll; i got error: "The specified module could not be found. (Exception from HRESULT: 0x8007007E)"

It means that problem is my PC sysem, sofware... not about the code.

 

Please help me to fix it, i spent two but still not found the reason.

 

 

Here the code i used:

 Function PopulateOIDCs(ByVal BlockName As String) _
As DatabaseServices.ObjectIdCollection
        Dim myBT As DatabaseServices.BlockTable
        Dim myBTR As DatabaseServices.BlockTableRecord
        Dim myBTRE As DatabaseServices.SymbolTableEnumerator
        Dim myDB As DatabaseServices.Database
        Dim myTransMan As DatabaseServices.TransactionManager
        Dim myTrans As DatabaseServices.Transaction
        Dim myOIDs As New DatabaseServices.ObjectIdCollection
        Dim myOIDs2 As DatabaseServices.ObjectIdCollection
        Dim I As Long
        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        myDB = acDoc.Database

        myTransMan = myDB.TransactionManager
        myTrans = myTransMan.StartTransaction
        myBT = myDB.BlockTableId.GetObject(DatabaseServices.OpenMode.ForRead)
        myBTR = myBT(BlockName).GetObject(DatabaseServices.OpenMode.ForRead)
        myOIDs2 = myBTR.GetBlockReferenceIds(True, False)
        For I = 1 To myOIDs2.Count
            myOIDs.Add(myOIDs2.Item(I - 1))
        Next
        myBTRE = myBT.GetEnumerator
        While myBTRE.MoveNext
            myBTR = myBTRE.Current.GetObject(DatabaseServices.OpenMode.ForRead)
            If myBTR.IsLayout = False Then
                Select Case myBTR.IsAnonymous
                    Case True
                        myOIDs2 = myBTR.GetBlockReferenceIds(True, False)
                        If myOIDs2.Count > 0 Then
                            Dim myBRef As DatabaseServices.BlockReference
                            myBRef = myOIDs2(0).GetObject(DatabaseServices.OpenMode.ForRead)
                            Dim myBTR2 As DatabaseServices.BlockTableRecord
                            myBTR2 = myBRef.DynamicBlockTableRecord.GetObject( _
                            DatabaseServices.OpenMode.ForRead)

                            If myBTR2.Name.CompareTo(BlockName) = 0 Then
                                For I = 1 To myOIDs2.Count
                                    myOIDs.Add(myOIDs2.Item(I - 1))
                                Next
                            End If
                        End If
                End Select
            End If
        End While
        myTrans.Dispose()
        myTransMan.Dispose()
        Return myOIDs
    End Function

16 REPLIES 16
Message 2 of 17
sszabo
in reply to: cokhitp

When you say "but this doesn't work" I assume you mean that's when you are getting the COM error HRESULT: 0x8007007E?  If yes, make sure that

1. acdbmgd in your project references is pointing to the correct autocad version's directory.

2. your DLL is registered with COM (regasm /tlb yourdll.dll) and you are netloading the registered version not some old version.

Message 3 of 17
norman.yuan
in reply to: cokhitp

Just my guess:

 

You are doing an stand-alone EXE application, aren't you? If so, you CANNOT use AutoCAD managed .NET API DLLs (acadmgd.dll/acmgd.dll).

Message 4 of 17
cokhitp
in reply to: sszabo

Dear sszabo;

 

"but this doesn't work" I assume you mean that's when you are getting the COM error HRESULT: 0x8007007E? -> Right.

 

1. acdbmgd in your project references is pointing to the correct autocad version's directory. --> I add .dll reference from the folder that install autocad.

 

2. your DLL is registered with COM (regasm /tlb yourdll.dll) and you are netloading the registered version not some old version. -> could you explain more?

 

Note: i format my PC, install VS and autocad. Can not happen that there is old .dll version.

 

Please help!

Message 5 of 17
cokhitp
in reply to: norman.yuan

Dear mornan.yuan

 

Yes, im making an stand-alone .exe application.

 

Which case i can use "AutoCAD managed .NET API DLLs (acadmgd.dll/acmgd.dll)"?

 

Now, for my application / stand-alone .exe which way i should follow?

 

Please help!

Message 6 of 17
sszabo
in reply to: cokhitp

I assumed you were working on an in-process DLL project.  norman.yuan is correct: you cannot do this from standalone EXE.  If you must control ACAD session from standalone EXE you have several options:

1. Write an In - PROC COM dll and expose it through .NET remoting or WCF to standalone applications

2. Write in proc .NET dll and do the same as above.

 

There is no way you can avoid the NETLOAD command either way.  You cannot use acdbmgd, accoremgd acmgd etc from standalone exe projects.

Message 7 of 17
norman.yuan
in reply to: cokhitp

Just my opinion:

 

1. Doing an EXE to automate AutoCAD is rarely an best solution, especailly the target user is AutoCAD user: If they use AutoCAD with their computer, why they have to run another application, which requires AutoCAD being running?

 

2. If you determined the external EXE app is the way to go, you can easily talk to AutoCAD from your app via AutoCAD's COM API. For your task (update attribute in block), the COM API is easy enough and more than enough to your task;

 

3. If you do not mind to make thing unnecessarily complicated, you can create DLL in .NET API and expose it to COM. Then you need to NETLOAD the DLL into AutoCAD before your app can communicate to your code running inside AutoCAD via COM.

 

4. You can also do DLL in .NET API and expose it via WCF endpoint. Then you can create a pure NET EXE app that communicate to your code in AutoCAD via WCF. Again, if you do not mind to make things more complicated to the task in hand.

 

Better and easy solution might be just doing it inside AutoCAD, because you need to run AutoCAD anyway.

Message 8 of 17
cokhitp
in reply to: norman.yuan

Dear norman and sszabo

 

The reason is i want to have a programe that automactic open alot of autocad drawing and take data from database and put data to attribute value.

 

And also after change attribute value, it can connect to printer to print.

 

Could you help me to define which way is the best?

 

 

 

Message 9 of 17
sszabo
in reply to: cokhitp

Just write your code that calls into ACAD core functionality as a COM DLL, register it using regasm yourdll.dll and write a standalone APP that connects to the running ACAD session, netloads your DLL and calls your functions such as PopulateOIDCs inside that DLL either via COM or .NET:

 

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim progID As String = "AutoCAD.Application.17"

        Dim acApp As AcadApplication

        acApp = Marshal.GetActiveObject(progID)

        acApp.Visible = True

        acApp.ActiveDocument.SendCommand("(command " & Chr(34) + "NETLOAD" & Chr(34) & ConvertToDoubleSlash("yourfull/path/to/yourdll.dll") & ")")

    End Sub

 

 

 You might have to fiddle with the exact command syntax, haven't actually ran it.

Message 10 of 17
cokhitp
in reply to: sszabo

Dear sszabo

 

The code got this error: "ConvertToDoubleSlash is not declared". Could you fix it?

 

Honestly, im newbie with this.

 

Thank so much.

Message 11 of 17
cokhitp
in reply to: cokhitp

Dear friends,

 

I have solved problem with this code:

--------------------------

        Const progID As String = "AutoCAD.Application.17"
        Dim acApp As AcadApplication = Nothing

        Try
            ' Intentar obtener la instancia activa
            acApp = DirectCast(Marshal.GetActiveObject(progID),  _
                             AcadApplication)

        Catch
            ' Si se produce un error
            Try
                ' Crear una instancia
                Dim acType As Type = Type.GetTypeFromProgID(progID)

                acApp = DirectCast(Activator.CreateInstance(acType, True),  _
                                AcadApplication)

            Catch
                ' Error ¿Esta Acad instalado?
            End Try

        End Try

        If acApp IsNot Nothing Then
            acApp.Documents.Open("E:\drawing1a.dwg")

            acApp.ActiveDocument.SendCommand("(command " & Chr(34) & "NETLOAD" & Chr(34) & " " & Chr(34) & "C:/Program Files/AutoCAD 2009/AcDx.dll" & Chr(34) & ") ")

        End If

----------------------------------

 

But now how i can change the value of attribute through my .exe application? Please help me? ^^ thank alots.

Message 12 of 17
sszabo
in reply to: cokhitp

Great!

Message 13 of 17
cokhitp
in reply to: sszabo

sszabo,

 

But now how i can change the value of attribute through my .exe application? Please help me? ^^ thank alots.

Message 14 of 17
sszabo
in reply to: cokhitp

1st method.

 

You can place your function in a new class project that has an interface exposing your function, compile the DLL yourdll.DLL and register it with COM.  Once ready you can create a new project for your exe, add your dll as a reference and you can get the COM interface with GetInterfaceObject() or with GetActiveObject() just as you did above.  Then you can either netload yourdll.DLL (not ac*.dll as you did above!) manually from ACAD or programatically via COM API using your interface object and then call your function.  That's the easiest. 

 

 

2nd method.

You can also create an in proc WCF server runnning inside autocad and talk to it from a WCF client running anywhere in the world as described in this video:

 

http://au.autodesk.com/?nd=event_class&jid=610987&session_id=7182

 

If you have problems let me know I might have some time this weekend to code up a simple example or find something on the web.

Message 15 of 17
cokhitp
in reply to: sszabo

sszabo,

 

Thank for your help!

 

I would like to use solution 1, but not clear understand. Cuold you help me to make a code example.

 

Please!!!!!

Message 16 of 17
sszabo
in reply to: cokhitp
Message 17 of 17
cokhitp
in reply to: sszabo

Dear sszabo,

 

Now i know how to make it.

 

I will inform if my programe can work fullly.

 

Thank alot.

 

If one day you come to VietNam, please contact me! ^^

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost