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

Newbie Confusion

6 REPLIES 6
Reply
Message 1 of 7
btillman
411 Views, 6 Replies

Newbie Confusion

I'm running AutoCAD 2013 Design Suite and VS 2013 Express. I'm trying to recreate some of the stuff I've done with VB.NET in opening up a drawing, loading and executing LISP etc. All of my work will be using the COM method that is it will be a stand-alone exe not running inside of AutoCAD. 

 

But try as I might I keep hitting this road block. Most of the article I read start out like this:

using System;
using System.Windows.Forms;

using System.Runtime.InteropServices;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;

 So I add a reference to AutoCAD 2013 Type Library but when I start typing using Autodesk.AutoCAD.Interop; etc... all I get in the intellisense is AutoCAD. Can anyone enlighten me on what I'm not doing correctly here?

 

6 REPLIES 6
Message 2 of 7
mcicognani
in reply to: btillman

Those includes are valid if you are developing a NET plugin that needs to reference also the COM interface of AutoCAD (sometimes you need it).

For your configuration (external exe with reference to AutoCAD Type Library), AutoCAD domain is all you'll get.

 

If I were you I'd thing about the absolute necessity to have an external exe and not an internal plugin. Development using only COM interface may be frustrating...

Message 3 of 7
mcicognani
in reply to: btillman

You may not even need a reference to the Type Library.

 

This sample get the latest AutoCAD object and make the SendCommand available.

 

public static void SendCommand(String szCommand)
{
    try
    {
        // get COM object for Application
        Object acadApp = Marshal.GetActiveObject("AutoCAD.Application");
        if (acadApp == nullreturn;
 
        // get current document
        object objDoc = acadApp.GetType().InvokeMember("ActiveDocument"BindingFlags.IgnoreCase | BindingFlags.GetProperty, null, acadApp, null);
        if (objDoc != null)
        {
            // get grip to windows handle
            object hwnd = objDoc.GetType().InvokeMember("HWND"BindingFlags.IgnoreCase | BindingFlags.GetProperty, null, objDoc, null);
            
            // get process associated to window
            int pid = 0;
            GetWindowThreadProcessId(new IntPtr(Convert.ToInt64(hwnd)), out pid);
            if (pid != 0)
            {
                // got it!
                System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(pid);
                SetForegroundWindow(p.MainWindowHandle);
                PostMessage(p.MainWindowHandle, WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
            }
        }
 
        // build parameters array for generic command
        object[] dataArray = new object[1];
        dataArray[0] = String.Copy(szCommand);
 
        // send command to current document
        //objDoc.GetType().InvokeMember("BringToFront", BindingFlags.IgnoreCase | System.Reflection.BindingFlags.InvokeMethod, null, objDoc, null);
        objDoc.GetType().InvokeMember("Activate"BindingFlags.IgnoreCase | BindingFlags.InvokeMethod, null, objDoc, null);
        objDoc.GetType().InvokeMember("SendCommand"BindingFlags.IgnoreCase | BindingFlags.InvokeMethod, null, objDoc, dataArray);
    }
    catch (System.Exception ex)
    {
 
    }
}

 

 

Message 4 of 7
btillman
in reply to: mcicognani

Okay, so do I have that backwards.... A COM program is one that is run inside of AutoCAD and anything else is run outside of AutoCAD as a stand-alone exe? Still very new to all this nomenclature. I'm looking right now in Visual Studio and when I try to add a reference it shows me that AutoCAD 2013 Type Library is under the COM objects and in the past I have used that entry to do my stand-alone exes....I'm really confused now.

 

And can anyone explain why when I open the Reference dialog window in Visual Studio I see no less than a dozen selections of the same AutoCAD 2013 Type Library?  All of them are the same version, same location on the disk, etc...

Message 5 of 7
btillman
in reply to: mcicognani

Thanks for sharing the code with me. I'm attempting to utilize it now in a new project. The problem is I open up Visual Studio 2013 Express, start a new C# Windows Application project and then I paste the above code into the editor. The first thing which happens is the Marhsal portion of the first line in the Try section gets redlined. The BindingFlags is also redlined as the GetWindowThreadProcessID. In all I end up with 13 errors. So I then add the AutoCAD 2013 Type Library reference but still have 13 errors. Can you offer a little more advice on how I could use this code?

 

Okay, sorry again for my newbie-ism. I found that by adding the System.Runtime.InteropServices and System.Reflection to the namespace area I got the number of errors down to only 4. I'm searching now for information on the other errors.

Message 6 of 7
mcicognani
in reply to: btillman

Sorry to have added confusion...

 

You can use COM both for instantiate external objects, like an application COM-enabled, and you may also get the COM interface of objects inside your application, like some third-part control or ActiveX.

 

Here, AutoCAD give you many options for automation, one is to use COM from an external exe and automate AutoCAD. Since the exe is external/independant, it really doesn't matter how you create it, you may use any language/compiler that support COM as interface.

 

Another option is to develop an application extension, a dll that will be loaded by AutoCAD and will run inside AutoCAD. Here you may use C/C++ (called ObjectARX) or .NET framework (C#, or any other .NET language). The interface here is defined by includes and library references for C/C++ or assemblies referencing for .NET. Since the extension, or plugin, will run inside the host, you have to match exactely the compiler and the NET framework used, otherwise your DLL will not work. Normally, for plug-ins, you don't need other comunication channels with the host application, because AutoCAD expose almost every function through NET interface. Almost, but not every, so, sometime, you may want to use COM even if you're inside a plug-in, because you want to access some internal functions not exposed through NET.

 

Now, I understand you want to use an external exe approach. This way you may use COM using standard Invoke() interface, a so called late-binding technique, because the application don't need to know the COM object during compilation, but will query the object only at runtime.

This technique may be used with different versions of the same application, but it's difficult to programme and it's generally slow during execution.

However, if you add a reference to the right Type Library, you may import the COM object definition before compilation, thus letting the compiler do the hard work of interfacing and letting the programmers to easy access to all methods and properties exposed by COM.

In our case, the reference is to "AutoCAD xxxx Type Library", where xxxx is the version you want to target.

As you may guess, targeting different AutoCAD versions cannot be done by the same project, since you can add only one Type Library for AutoCAD.

 

So, back to my early post: since programming a pure COM interface is really expensive, it's common practice to add reference to a Type LIbrary, even if this means to tie your project to a specific AutoCAD version. But given this drawback, why not jumping directly inside and develop a plug-in?

You'll have better access to AutoCAD resources, like dialog boxes, palettes and CUIx, and the autoloader mechanism make the software distribution easy even when supporting multiple AutoCAD versions. Just my penny.

 

 

 

 

Message 7 of 7
mcicognani
in reply to: btillman

For the code snippet I posted:

 

That function is taken from a C# project compiled against NET Framework 4.5.1, but should work from 3.5 and above, not sure here...

 

The module use these includes, try to add them on top of your class, sure thing not everyone is needed, but I have no time to check..

And of course you need a class, even if the function is static.
Something like this:

 

using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Win32;
using System.Security.Cryptography;
using System.Security;
using System.Reflection;

namespace MyBigApplication
{
    public static class csUtilities
    {

// put your static functions here

}
}

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