Author Topic: Trouble Creating COM Component  (Read 2279 times)

0 Members and 1 Guest are viewing this topic.

sling blade

  • Guest
Trouble Creating COM Component
« on: January 20, 2015, 07:50:03 PM »
I am trying to work from this Through The Interface tutorial here: http://through-the-interface.typepad.com/through_the_interface/2009/05/interfacing-an-external-com-application-with-a-net-module-in-process-to-autocad-redux.html

I am trying to build the COM visible component from the article but when I do the compiler tells me it could not register my assemblly because it could not load one of my referenced dll's. If I compile the code without [assembly: ComVisible(true)] i.e. I use [assembly: ComVisible(false)] then it compiles ok.

This is the compiler error:

Error   4   Cannot register assembly "E:\Visual Studio 2013\AutoCAD\LoadableComponent\LoadableComponent\bin\Debug\LoadableComponent.dll". Could not load file or assembly 'accoremgd, Version=19.1.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.   LoadableComponent


The LoadableComponent.dll is created but compiler says Build Failed with the error I mentioned.

* update : I have now moved the output directory to the autocad install directory but I still receive the same error message

If someone wants to compile this themselves I have uploaded my dll's to Google Drive here: https://drive.google.com/a/slingblade.co.nz/folderview?id=0B-NzIeN88P9lVkdvTXhHSTlrUWM&usp=sharing

Here is the code:
Code: [Select]
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.EditorInput;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.Runtime;
    using Autodesk.AutoCAD.Geometry;
    using System.Runtime.InteropServices;
    using System.EnterpriseServices;
   
   
    namespace LoadableComponent
    {
        [Guid("F26BAC4F-B905-4678-B10B-BF548FAFA3AE")]
        public interface INumberAddition
        {
            [DispId(1)]
            string AddNumbers(int arg1, double arg2);
        }
   
        [ProgId("LoadableComponent.Commands"),
            Guid("3EB8AB8D-1E3F-4BA6-BCD3-EC954A756C16"),
            ClassInterface(ClassInterfaceType.None)]
        public class Commands : ServicedComponent, INumberAddition
        {
            // A simple test command, just to see that commands
            // are loaded properly from the assembly
   
            [CommandMethod("MYCOMMAND")]
            static public void MyCommand()
            {
                Document doc =
                    Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                ed.WriteMessage("\nTest command executed.");
            }
   
            // A function to add two numbers and create a
            // circle of that radius. It returns a string
            // with the result of the addition, just to use
            // a different return type
   
            public string AddNumbers(int arg1, double arg2)
            {
                // During tests it proved unreliable to rely
                // on DocumentManager.MdiActiveDocument
                // (which was null) so we will go from the
                // HostApplicationServices' WorkingDatabase
   
                Document doc =
                    Application.DocumentManager.MdiActiveDocument;
                Database db = doc.Database;
                Editor ed = doc.Editor;
   
                ed.WriteMessage(
                    "\nAdd numbers called with {0} and {1}.",
                    arg1, arg2
                );
   
                // Perform our addition
   
                double res = arg1 + arg2;
   
                // Lock the document before we access it
   
                DocumentLock loc = doc.LockDocument();
                using (loc)
                {
                    Transaction tr =
                        db.TransactionManager.StartTransaction();
                    using (tr)
                    {
                        // Create our circle
   
                        Circle cir =
                            new Circle(
                            new Point3d(0, 0, 0),
                            new Vector3d(0, 0, 1),
                            res
                            );
   
                        cir.SetDatabaseDefaults(db);
   
                        // Add it to the current space
   
                        BlockTableRecord btr =
                            (BlockTableRecord)tr.GetObject(
                            db.CurrentSpaceId,
                            OpenMode.ForWrite
                            );
                        btr.AppendEntity(cir);
                        tr.AddNewlyCreatedDBObject(cir, true);
   
                        // Commit the transaction
   
                        tr.Commit();
                    }
                }
                // Return our string result
                return res.ToString();
            }
        }
    }


Can someone help me understand what I am doing wrong? Like I said it compiles ok if I don't have the com visible switch set to true.

Since the LoadableComponent.dll creates I try to use it anyway and when I do I get this error when I try to communicate through COM:

Unable to cast COM object of type 'System.__ComObject' to interface type 'LoadableComponent.INumberAddition'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{F26BAC4F-B905-4678-B10B-BF548FAFA3AE}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).


BTW I have NETLOAD'ed the dll in AutoCAD.

Here is the code from my .net app. I simple have a blank form with a button. Here is the code found under the button. I have commented below where the code is failing,
Code: [Select]
    private void button1_Click(object sender, EventArgs e)
        {
            const string progID = "AutoCAD.Application.19.1";
   
            AcadApplication acApp = null;
            try
            {
                acApp =
                  (AcadApplication)Marshal.GetActiveObject(progID);
            }
            catch
            {
                try
                {
                    Type acType =
                      Type.GetTypeFromProgID(progID);
                    acApp =
                      (AcadApplication)Activator.CreateInstance(
                        acType,
                        true
                      );
                }
                catch
                {
                    MessageBox.Show(
                      "Cannot create object of type \"" +
                      progID + "\""
                    );
                }
            }
            if (acApp != null)
            {
                try
                {                   
                    acApp.Visible = true;
   
                    INumberAddition app =
                      (INumberAddition)acApp.GetInterfaceObject(
                        "LoadableComponent.Commands"
                      );
   
                    //====here is where I get the error====
   
                    string res = app.AddNumbers(5, 6.3);
   
                    acApp.ZoomAll();
   
                    MessageBox.Show(
                      this,
                      "AddNumbers returned: " + res
                    );
                }
                catch (Exception ex)
                {
                    MessageBox.Show(
                      this,
                      "Problem executing component: " +
                      ex.Message
                    );
                }
            }
        }
« Last Edit: January 21, 2015, 02:46:41 AM by sling blade »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Trouble Creating COM Component
« Reply #1 on: January 20, 2015, 09:28:45 PM »

Perhaps you could post a comment to Kean's blog asking him to have a look here at your issue ..
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.