In Windows 7-x64, I get a "Cannot create ActiveX component" error when trying to launch AutoCAD 2010-x64 with CreateObject. I am compiling my VB.Net 2008 project as x64-Release and the version of AutoCAD is the x64 version.
What is interesting is that I can successfully late-bind to 32-bit Excel x86 from this same app.
The reason I am trying to do so is that I have a VB.Net 2005 app compiled as x86, that runs fine on Win7-x64, but fails to late-bind to AutoCAD 2010 (with the same error) because it is the 64-bit version. My plan is to make the dialog with this code a stand-alone x64 application, which *should* be able to late-bind to AutoCAD-x64...
Here is my code:
Private Sub OpenACAD()
Try
mACAD = CreateObject("AutoCAD.Application") '<---This doesn't work
'mACAD = CreateObject("AutoCAD.Application.18") <-- This doesn't work either
mDWG = mACAD.Documents.Item(0)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
I have a similar problem, only my application is using GetObject(,"AutoCAD.Application")
In my situation, I won't know what version of AutoCAD is installed on the user's machine, so the intent is to obtain a pointer to the open session of AutoCAD of the most recent version. It doesn't seem to matter which version is in use, it won't work on a 64-bit machine.
Dim sNames() As String = {".18", ".17", ".16", ".15", ".14"}
Dim iName As Integer
iName = 0
Do While objACADApp Is Nothing And iName < UBound(sNames)
Try
objACADApp = GetObject(, "AutoCAD.Application" & sNames(iName))
Catch ex As Exception
'do nothing
End Try
iName = iName + 1
Loop
I don't mean to piggy-back on spanqy's post, but I think there's a similar mechanism at work.
Any help you can offer is appreciated...
Clint
Spanqy,
I have used reflection to do late binding before, and decided to Google something based on reflection. This is what I came up with. I haven't checked it yet myself, but thought maybe between the two of us we could figure out if this is the solution to our problems...
http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/5f4bfa02-4db3-4890-b64d-dccd99c584ec
Overland
Seems like spangy already has a solution, for the version problem I would suggest simply investigating the registry keys named ACADLOCATION for each version of AutoCAD you need to test for, find out where each one is stored for 32-bit and 64-bit OSes which may include 32-bit AutoCAD's installed on 64-bit OSes before AutoCAD became a true 64-bit app.
If you can find the registry key and verify that acad.exe resides at the location specified then you can check off that version of AutoCAD as installed. Here is some code that I use:
Public Structure ProductType
Public Name As String
Public Location As String
Public Release As String
Public Key As String
Public Version As String
Public Year As String
Public RoamingName As String
End Structure
Dim Products() As ProductType
Dim OS64Bit As Boolean Dim Releases(0 To 0) Releases32(0 To 0) As String OS64Bit = (IntPtr.Size = 8) Releases(0) = "" Releases32(0) = "" If GetReleases(Releases, Releases32) Then If GetProducts(Releases, Releases32) Then 'Success Else 'Could not locate any AutoCAD products End If Else 'Could not locate any AutoCAD product releases End If Public Function GetReleases(ByRef Releases() As String, ByRef Releases32() As String) As Boolean Dim MachineReg As RegistryKey Dim sList() As String Dim a, b, c As Integer b = 0 Try MachineReg = Registry.LocalMachine.OpenSubKey("Software\Autodesk\AutoCAD", RegistryKeyPermissionCheck.ReadSubTree, Security.AccessControl.RegistryRights.ReadKey) sList = MachineReg.GetSubKeyNames For a = 0 To UBound(sList) ' find subkeys of the form "Rnn.n" If sList(a).ToUpper Like "R[1-9]#.#" Then ReDim Preserve Releases(0 To b) Releases(b) = sList(a) b = b + 1 End If Next Catch ex As Exception End Try c = 0 Try MachineReg = Registry.LocalMachine.OpenSubKey("Software\Wow6432Node\Autodesk\AutoCAD", RegistryKeyPermissionCheck.ReadSubTree, Security.AccessControl.RegistryRights.ReadKey Or &H200) sList = MachineReg.GetSubKeyNames For a = 0 To UBound(sList) ' find subkeys of the form "Rnn.n" If sList(a).ToUpper Like "R[1-9]#.#" Then ReDim Preserve Releases32(0 To c) Releases32(c) = sList(a) c = c + 1 End If Next Catch ex As Exception End Try GetReleases = ((b > 0) Or (c > 0)) End Function Public Function GetProducts(ByRef Releases() As String, ByRef Releases32() As String) As Boolean Dim VersionReg, ProductReg As RegistryKey Dim key1, key2, val1, val2, val3, sList() As String Dim a, b, c As Integer Dim App64Bit, Done As Boolean Dim TempProd As ProductType c = 0 Try For a = 0 To UBound(Releases) If Releases(a) = "" Then Exit For key1 = "Software\Autodesk\AutoCAD\" & Releases(a) VersionReg = Registry.LocalMachine.OpenSubKey(key1, RegistryKeyPermissionCheck.ReadSubTree, Security.AccessControl.RegistryRights.ReadKey) sList = VersionReg.GetSubKeyNames For b = 0 To UBound(sList) If sList(b).ToUpper.StartsWith("ACAD-") Then key2 = key1 & "\" & sList(b) ProductReg = Registry.LocalMachine.OpenSubKey(key2, RegistryKeyPermissionCheck.ReadSubTree, Security.AccessControl.RegistryRights.ReadKey) val1 = ProductReg.GetValue("ProductName", "") val2 = ProductReg.GetValue("AcadLocation", "") val3 = ProductReg.GetValue("ProductNameShort", val1) If val1.Length > 0 And val2.Length > 0 Then App64Bit = (OS64Bit And val2.ToLower.Contains("x86").Equals(False)) ReDim Preserve Products(0 To c) Products(c).Name = val1 & IIf(App64Bit, " (64-bit)", " (32-bit)") Products(c).Release = Releases(a) Products(c).Key = key1 Products(c).Version = sList(b) Products(c).Location = val2 Products(c).Year = val1.Substring(val1.Length - 4) Products(c).RoamingName = val3 c = c + 1 End If End If Next Next Catch ex As Exception End Try Try For a = 0 To UBound(Releases32) If Releases32(a) = "" Then Exit For key1 = "Software\Wow6432Node\Autodesk\AutoCAD\" & Releases32(a) VersionReg = Registry.LocalMachine.OpenSubKey(key1, RegistryKeyPermissionCheck.ReadSubTree, Security.AccessControl.RegistryRights.ReadKey) sList = VersionReg.GetSubKeyNames For b = 0 To UBound(sList) If sList(a).ToUpper.StartsWith("ACAD-") Then key2 = key1 & "\" & sList(b) ProductReg = Registry.LocalMachine.OpenSubKey(key2, RegistryKeyPermissionCheck.ReadSubTree, Security.AccessControl.RegistryRights.ReadKey) val1 = ProductReg.GetValue("ProductName", "") val2 = ProductReg.GetValue("AcadLocation", "") val3 = ProductReg.GetValue("ProductNameShort", val1) If val1.Length > 0 And val2.Length > 0 Then App64Bit = (OS64Bit And val2.ToLower.Contains("x86").Equals(False)) ReDim Preserve Products(0 To c) Products(c).Name = val1 & IIf(App64Bit, " (64-bit)", " (32-bit)") Products(c).Release = Releases32(a) Products(c).Key = key1 Products(c).Version = sList(b) Products(c).Location = val2 Products(c).Year = val1.Substring(val1.Length - 4) Products(c).RoamingName = val3 c = c + 1 End If End If Next Next Catch ex As Exception End Try If c > 0 Then Done = False Do While Not Done b = 0 Done = True Do While b < UBound(Products) If Val(Products(b).Year) > Val(Products(b + 1).Year) Then TempProd = Products(b) Products(b) = Products(b + 1) Products(b + 1) = TempProd Done = False ElseIf Val(Products(b).Year) = Val(Products(b + 1).Year) Then If Products(b).Name.Length > Products(b + 1).Name.Length Then TempProd = Products(b) Products(b) = Products(b + 1) Products(b + 1) = TempProd Done = False End If End If b = b + 1 Loop Loop End If GetProducts = (c > 0) End Function
I found the answer to my question this morning after a nice 4-day weekend...
My project was compiled in x64-Debug mode, not x64-Release as I thought. Makes sense as the Acad.exe file is obviously in Release mode too.
Thanks for sharing all the info. Looks like it could prove handy.
Mark