Jump to content

Launch AutoCAD from VB.NET Program


Recommended Posts

Posted

I have a nice method for launching AutoCAD from an Excel VBA program but now we're moving over to a VB.NET application. Will the code for VBA work for VB.NET?

 

I usually find that the codes do not interchange very well.

Posted

VBA VB.NET :thumbsup:

 

In an effort to save yourself some grief, consider using Shell to open a specific application icon (which includes the applicable startup switches already), if there is not a current instance (i.e., a Process) for you to access. A while back, I gave you an example of this from an Excel application that would 'get or create'.

Posted

Renderman,

 

Yes, I recall that well and I used it for a while, however, several of the IT guys here told me that using Shell from a VBA program was frowned upon...by them at least. As I recall from my long ago days of programming in BASIC, the shell command, while useful, left the original code in control. And if the application had a problem, it would be hard to trace, etc...I know things have come a long way from that time, but I have always stayed away from the Shell command, mainly for this reason.

 

The current VBA method I'm using is like this, and you will notice it allows me to put in the needed arguments to launch the correct LISP program and execute it:

 

Set acDoc = acApp.Documents.Open(strDrawing)
acDoc.Activate
Set acDoc = acApp.ActiveDocument
acDoc.SendCommand ("(load ""//a_very_long/path/deep_inside/a_novell_network/MyLisp.lsp"" ""The load failed"") mylisp" & Chr(13))

I'm looking for something that is VB.NET compatible and our good friend Fixo had a posting on another forum which I modified. It works well but it opens AutoCAD in a small window, not maximized, which is what I'm after.

 

Now, I would like to add this caveat. I have been learning VB.NET because the IT guys here tell me that it's .NET or the highway. I don't make the rules, I just follow them. They want me to wean the engineering department off of VBA as soon as possible. No problem, I love a challenge and thus far we've made some decent progress, But as I look at Fixo's code to launch AutoCAD from VB.NET it's hard to fathom how one could program this from scratch. Long ago with BASICA and QBASIC is was not that difficult to build new and exciting things from scratch. But this block of code for this class is 24 lines long and has strings in it that are a meter long. The IDE in VB 2010 Express which I'm using makes it easy to type the stuff in, but to try and find where someone would have come up with this code in the first place has been the challenge. Like I showed someone this morning, I used to open a file and read lines of text in with just 3 or 4 lines of code. With VB.NET it now takes about 12 or 15 lines of code to do the very same thing. And the namespace requirements....every time I find something which claims it will work, the poster failed to include the Import statements...which as you well know, render the rest of the code useless...and until such time that I'm as familiar with all the nuisances with .NET I'm kind of stuck with asking for lots of advice. And if anyone wants to argue the point, I'll be glad to show how lacking the available documentation on this subject is. I read dozens of articles each day and night which are missing imperative points, have typos of all kinds and just plain useless because the author assumes anyone reading it knows as much about it as they do.

 

Sorry for the rant...! I do appreciate everyone's assistance on these forums.

Posted

I am no full-time professional developer myself, but methinks we're talking about two different things with regard to Shell... You mention the Shell Command specifically, and I am suggesting that you consider incorporating the Shell.Application Object (i.e., Windows Shell?) into your VB.NET application for launching AutoCAD (outside of AutoCAD, i.e., from a stand-alone EXE).

 

The VB.NET example I provided you previously (the one for Excel) would first check for an instance of Excel (read: a Process), and if present, 'get' the Excel Application Object, otherwise, if no instance of Excel (read: a Process) existed, a new one would be created.

 

Following this concept, you can (again, from a stand-alone application outside of AutoCAD) check for an Active instance of AutoCAD (Process), and if none exist, use the Shell.Application Object to launch AutoCAD using the specified Application Icon (read: Shortcut, or .LNK) which will include the applicable Profile switch (/p), etc..

 

... Does this make (more?) sense to you now?

 

Please clarify, are you performing this task within, or outside of AutoCAD? The OP mentions 'launching AutoCAD', but your last example is ambiguous but suggests using SendCommand from within AutoCAD. Not really sure.

 

As for the amount of code in .NET vs. LISP, VBA, etc... Believe me, I know... But that's the way it is if you want to use the upper level, full-blown development environments. :thumbsup:

 

As for the missing Imports... You say you're using Visual Studio 2010 Express, right? So paste the code into a blank Class (i.e., *.vb, *.cs, or other), and hover the error, select the down arrow that appears and check to see what options are available. Often times (provided you have the necessary Assemblies referenced) you'll be presented with an option to add the necessary 'Imports' (VB), or 'using' (C#) statement to the Class.

 

.NET development requires a greater knowledge level than a LISP, or VBA developer; that's just a fact. You should have all of the necessary ObjectARX SDKs installed for your version(s), and using a Wizard (again because you're using Express) helps with a lot of the repeated tasks of adding certain reference Assemblies, enabling Debugging, etc..

 

I know you're doing this for work and all, but the better your information (and code?) up front, the easier it will be for myself, or others to assist you. :thumbsup:

Posted

I've gotten the process condensed down to this:

 

Imports Autodesk.AutoCAD.Interop.AcadDocumentClass
Imports Autodesk.AutoCAD.InterOp.Common

Module Module1

   Sub Main()
       Dim vAcadApp As Autodesk.AutoCAD.Interop.AcadApplication
       Dim vAcadDoc As Autodesk.AutoCAD.Interop.AcadDocuments
       vAcadApp = New Autodesk.AutoCAD.Interop.AcadApplication
       vAcadApp.Visible = True
      
   End Sub

End Module

 

Now this is what I'm talking about. A few lines of code to do what the other 24 lines did. The trouble with this is that it open up AutoCAD in a small, narrow window. Do you think this will work by adding some additional information to open a template file and then launch one of the LISP programs?

Posted

Sorry to ask again, but can you please clarify... Stand-alone EXE (outside of AutoCAD), or .NET plug-in (inside of AutoCAD, and get's NETLOADed)...? :unsure:

 

Also, if you could link (or post) Fixo's code that would be helpful as well... Just want a better understanding of where you were, and are now.

Posted

Renderman,

 

Yes sir. I saw that other posting and I highly agree. I am a full-time developer. Why? Because they couldn't find anyone else around here stupid enough to take it on. But like I said, I do love a challenge. I don't claim to know everything about the problem with the SHELL command, I only know what the IT guys here advise me on and I don't want to get caught with my fly open in a meeting where some problem with the network was caused by something they warned me against.

 

All of the VBA code I am writing is performed from an Excel spreadsheet. And the VB.NET code I'm working on is of course stand-alone. Only the LISP codes I prepare are running inside of AutoCAD. The sendCommands I use are in the VBA codes which run from the Excel files. That all works very well. But the new process I'm working on will not be VBA. The same LISP programs will be used but we're moving away from VBA to VB.NET.

 

I use VB 2010 Express...not Visual Studio. It's allegedly a watered down version of VS and only contains the VB.NET language. It's FREE...and that's what I sold them on. I've been advised by others that the Express version has plenty of capabilities to do what I want...and so far it appears to be up to the task. If the time comes when it will not, then I will have some ammunition to request a budget for Visual Studio...although they do have several seats for VS 2005 around here. The trouble with that is that 2005 may as well be 1985 because the .NET codes required here are not compatible. I have to be careful on my requests for purchases, especially now because they just bought a new license for Acad 2013...and billed it to my department. Until I show them an ROI on that it will be difficult to ask for a new VS seat.

 

As for the Imports, I have noticed that sometimes....sometimes, the error messages will present either what to Import or make a suggestion about it. But in many instances, there is only an error which says "no go" and I'm stuck with finding another method.

Posted

Here is the link to the code I found from Fixo. It's way down the page at post #12. Fixo is really good at this kind of stuff and he has been a big help in the past. I sent him a PM with the code I modified to see if he has time to assist. The code works and it will actually open an existing drawing, which is what I'm eventually going to have to do, like the VBA code I am using now. It also opens AutoCAD up in a very tall and narrow window instead of maximized. In addition, I will need to load and execute the LISP program.

 

http://www.dreamincode.net/forums/topic/244731-how-to-connect-to-autocad-and-open-a-drawing/

 

Here is the code from Fixo as I have modified it. It was actually a form, but I am working on a user-input-less process so I changed it over to a Console Application.

 

Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Globalization
Imports System.Collections

Public Class ReflectionCommands

   <System.Security.SuppressUnmanagedCodeSecurity()> _
   Public Shared Sub TestACAD(ByVal dwgname As String)
       'Save current culture to variable
       Dim thisThread As System.Globalization.CultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture
       'Set culture to whatever you want
       thisThread = New System.Globalization.CultureInfo("en-US")
       Dim appProgID As String = "AutoCAD.Application"
       Dim filename As String = dwgname
       'NGet reference on intergrace IDispatch
       Dim AcadType As Type = Type.GetTypeFromProgID(appProgID)

       'Launch AutoCAD
       Dim AcadApp As Object = Activator.CreateInstance(AcadType)
       Dim visargs() As Object = New Object(0) {}
       visargs(0) = True
       'Set Application Window visible
       AcadApp.GetType().InvokeMember("Visible", BindingFlags.SetProperty, Nothing, AcadApp, visargs, Nothing)
       Dim AcadDocs As Object = AcadApp.GetType().InvokeMember("Documents", BindingFlags.GetProperty, Nothing, AcadApp, Nothing)

       'Create array of parameters
       Dim args() As Object = New Object(1) {}
       args(0) = filename
       args(1) = False ' read-only=false
       'open a drawing
       Dim AcDoc As Object = AcadDocs.GetType.InvokeMember("Open", BindingFlags.InvokeMethod, Nothing, AcadDocs, args, Nothing)
       Dim Util As Object = New Object
       Try
           'Get reference on active document
           AcDoc = AcadApp.GetType.InvokeMember("ActiveDocument", BindingFlags.GetProperty, Nothing, AcadApp, Nothing, Nothing)
           'Get reference on AcadUtility
           Util = AcDoc.GetType().InvokeMember("Utility", BindingFlags.GetProperty, Nothing, AcDoc, Nothing)
           'Get reference on ModelSpace
           Dim oSpace As Object = AcDoc.GetType.InvokeMember("ModelSpace", BindingFlags.GetProperty, Nothing, AcDoc, Nothing)

       Catch ex As Exception

       End Try

   End Sub
End Class
Module Module1

   Sub Main()
       Dim fname As String = "H:\Test123.dwg"
       ReflectionCommands.TestACAD(fname)
   End Sub

End Module

Posted (edited)

Renderman,

 

At the risk of making this post too long and too boring for most folks, here is some of what I accomplished last night. Again, my newbie status with .NET is clear to see but I'm trying to make use of a shorter version of this code.

 

Imports Autodesk.AutoCAD.Interop.AcadDocumentClass
Imports Autodesk.AutoCAD.InterOp.Common

Module Module1

   Sub Main()
       Dim vAcadApp As Autodesk.AutoCAD.Interop.AcadApplication
       Dim vAcadDoc As Autodesk.AutoCAD.Interop.AcadDocument
       vAcadApp = New Autodesk.AutoCAD.Interop.AcadApplication

       vAcadApp.Visible = True
       vAcadApp.WindowState = AcWindowState.acMax

       'vAcadDoc = vAcadApp.Documents.Open("I:\Automated Drawings\APS(Automated).dwg", True)
       'vAcadDoc.SendStringToExecute("(load ""//mypath/mylisp.lsp"" ""The load failed"") mylisp" & Chr(13))

   End Sub

End Module

 

OK, I had to change the keyword AcadDocuments to AcadDocument...and that seemed to have fixed the exception error. This works now and it maximizes the window. I just need to get the LISP program loaded and executed.

Edited by Bill Tillman
Posted

The sweet smell of success. Or at least the darn thing is working now.

 

The SendCommandToExecute method did not work, or maybe there is another import required for it. I will research that more because the initial information I got from AutoDesk's forum said that SendCommand is not recommended for VB.NET. That may well be true but I found many other articles which said no problem.

 

Anyway, here is the code, which now opens Autocad, opens the template drawing, loads the lisp and executes it and poof....there is my requested assembly drawing all done in about 10 seconds instead of the usual 2-3 hours.

 

Imports Autodesk.AutoCAD.Interop.AcadDocumentClass
Imports Autodesk.AutoCAD.Interop.Common

Module Module1

   Sub Main()
       Dim vAcadApp As Autodesk.AutoCAD.Interop.AcadApplication
       Dim vAcadDoc As Autodesk.AutoCAD.Interop.AcadDocument
       vAcadApp = New Autodesk.AutoCAD.Interop.AcadApplication

       vAcadApp.Visible = True
       vAcadApp.WindowState = AcWindowState.acMax
       vAcadDoc = vAcadApp.Documents.Open("I:\Automated Drawings\Automated.dwg", True)
       vAcadDoc.SendCommand("(load ""//a_very_long_novell/server_path/LISP/mylisp.lsp"" ""The load failed"") mylisp" & Chr(13))

   End Sub

End Module

Posted

... Now you just need to code your LISP into .NET :P :lol:

 

 

Congrats, Bill! :beer:

Posted

Before I forget, to make your code more 'portable' there's a couple of things you can do:

 

Instead of coding the entire solution in Main(), consider writing a Method that accepts two arguments, a DWT as String, and a LSP as String. This Method can go into your code library, and can easily be added as a Reference Assembly to any other solution.

 

Going one step further, these arguments as Strings may not require the file path, provided they both reside within the Support File Search Path (SFSP), as you can use the HostApplicationServices.FindFile() Method... As shown in this thread. Gile's awesome! :geek: :notworthy:

 

HTH

Posted

As for moving all the LISP to .NET, I'd do it except the big boss will come in and ask me why I'm reinventing the wheel. In other words, if it ain't broke, don't fix it.

 

And as for using variables for the DWT, etc...that's a great idea and I've already got that working. The LISP file and the drawing template which this will open are all based on whatever the first part of my project found in the text file it read. It's coming together nicely. Thanks again for the very helpful advice.

Posted

It's coming together nicely. Thanks again for the very helpful advice.

 

Happy to have helped, Bill. :beer:

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...