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

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

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
swaywood
11568 Views, 12 Replies

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

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

12 REPLIES 12
Message 2 of 13
Keith.Brown
in reply to: swaywood

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
in reply to: Keith.Brown

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

Message 4 of 13
_gile
in reply to: swaywood

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
in reply to: _gile

hi gile:

   thks

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

swaywood

Message 6 of 13
mcicognani
in reply to: swaywood

Something like:
System.Reflection.Assembly.LoadFrom(szYourDllPath);
Message 7 of 13
swaywood
in reply to: mcicognani

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");
    }
  }
}
Message 8 of 13
_gile
in reply to: swaywood

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

Message 9 of 13
norman.yuan
in reply to: swaywood

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
in reply to: norman.yuan

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

Message 11 of 13
swaywood
in reply to: _gile

hi gile:

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

swaywood

 

Message 12 of 13
_gile
in reply to: swaywood

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

Message 13 of 13
swaywood
in reply to: norman.yuan

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

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