how to load a dll and run the command by a method in a command?

how to load a dll and run the command by a method in a command?

swaywood
Collaborator Collaborator
14,520 Views
12 Replies
Message 1 of 13

how to load a dll and run the command by a method in a command?

swaywood
Collaborator
Collaborator

hi all:

    i have 2 dlls. one is a.dll, the other is b.dll.

    and a1 is one of the command in a.dll. b1 is one of the command in b.dll

    now i netload a.dll and run the a1 command.

    in a1 command method how to load b.dll and run b1 command?

    please don't ask me why not netload a.dll and b.dll together…

thanks

swaywood

0 Likes
Accepted solutions (1)
14,521 Views
12 Replies
Replies (12)
Message 2 of 13

Keith.Brown
Advisor
Advisor

I believe that Autocad will not recognize the command in the b.dll unless you netload it.  That being said, every custom command in .NET has a corresponding method that goes with it.  In your A.dll just reference the B.dll and then inside of the command in the A.dll just call the method that corresponds to the command in the B.dll.  Autocad should load it and then run the method.

Message 3 of 13

swaywood
Collaborator
Collaborator

hi Brown,

    thank you for your reply. in my case ,a.dll is not reference b.dll. i want to use 'System.Reflection' to load dll file.

swaywood

0 Likes
Message 4 of 13

_gile
Consultant
Consultant

Hi,

 

What about using Editor.Command() method for A2015+ or a RunCommand() wrapper (for prior versions) ?

 

ed.Command("_netload", "b.dll");
ed.Command("b1");


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 13

swaywood
Collaborator
Collaborator

hi gile:

   thks

   yes use ed.command maybe ok, but i'd like to try other method instead of cmd.

swaywood

0 Likes
Message 6 of 13

Anonymous
Not applicable
Something like:
System.Reflection.Assembly.LoadFrom(szYourDllPath);
Message 7 of 13

swaywood
Collaborator
Collaborator

i tried this codes, but not success yet. cad version is 2010

    public void prjOnlineUpdate()
    {
      object obj = null;
      byte[] filesByte;
      Assembly assembly;
      Type type;
      try
      {
        string folder = Environment.CurrentDirectory;
        if (folder[folder.Length - 1] == '\\')
        {
          folder = folder.Remove(folder.Length - 1);
        }
        //filesByte = File.ReadAllBytes(folder + "//cmdtest.dll");
        //assembly = Assembly.Load(filesByte);
        assembly = Assembly.LoadFrom(folder + "//cmdtest.dll");
        type = assembly.GetType("cmdtest.Class1");
        obj = System.Activator.CreateInstance(type);
        MethodInfo timerStart = type.GetMethod("test");
        if (timerStart != null)
        {
          timerStart.Invoke(obj, null);
        }
      }
      catch (System.Exception)
      {

      }
    }

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace cmdTest
{
  public class Class1
  {
    [CommandMethod("test")]
    public void test()
    {
      Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
      ed.WriteMessage("test is ok");
    }
  }
}
0 Likes
Message 8 of 13

_gile
Consultant
Consultant

Did you try just doing:

 

 

System.Reflection.Assembly.LoadFrom(Path.Combine(Environment.CurrentDirectory, b.dll));
ed.Command("b1");

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 13

norman.yuan
Mentor
Mentor
Accepted solution

As you already mentioned, if the a.dll has reference to b.dll, then you do not need to "NETLOAD" b.dll, because when a.dll is netloaded, b.dll is also loaded because of the reference.

 

However, as you requested, you could load b.dll using System.Reflection whenever needed: Assembly.Load()/LoadFile()/LoadFrom() (there are subltle differences among the 3 loading methods that you need to pay attention). Assembly loaded this way is the same as loaded by Acad's "NETLOAD" command (and the IExtensionApplication will run upon loading). Better yet, before you load the DLL assembly, you not only make sure the dll is in the .NET loading location according to .NET loading poll-mechnism; but also check if the assembly has already been loaded, to which you can use AppDomain.CurrentDomain.GetAssemblies() to find out loaded .NET assemblies (by its fully qualified name/version...).

 

Fortunately, the Autodesk.AutoCAD.Runtime.ExtensionLoader class (available since Acad2013?) has Load()/IsLoaded to do exactly the things aforementioned in more simplfied way.

 

HTH.

Norman Yuan

Drive CAD With Code

EESignature

Message 10 of 13

swaywood
Collaborator
Collaborator

hi yuan:

   thank you for your reply. i tried 3 load methods, but allways did not get the type(type = null), then 'obj = System.Activator.CreateInstance(type);' got error. could you help me write a test solution based on the code i post? the 2 dll does not reference each other. thank you so much.

swaywood

0 Likes
Message 11 of 13

swaywood
Collaborator
Collaborator

hi gile:

   thanks for your kindly help, but  i use autocad 2010, there is no ed.Command method.

swaywood

 

0 Likes
Message 12 of 13

_gile
Consultant
Consultant

In my first reply, I gave you a link to a topic where DinningPhilosopher (aka Tony Tanzillo) provided a wrapper for the undocumented RunCommand() method. You can also search for acedCmd P/Invoking methods.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 13 of 13

swaywood
Collaborator
Collaborator

Hi yuan:

   Your words solve my problem, thanks again!

   First I use 'ExtensionLoader' to load the dll. And use 'AppDomain.CurrentDomain.GetAssemblies()' to get the 'Assembly'. Then I can run the command method now.

   By the way, the 'ExtensionLoader' class is available in acad2010.

swaywood

0 Likes