A big thank you to Jim Cameron from Dematic for providing the code for this post, and to Wayne Brill from DevTech Americas who helped him on his way via ADN support. I’ve made a few changes of my own to the code, but the concept is very much Jim’s.
Jim recently had a frustrating problem with a VLX application he wrote that depends – via (vl-arx-import) – on a .NET module. It turns out the module was not being demand-loaded properly, but this took some time to diagnose. In the past Jim used (arx) from LISP to detect the loaded ObjectARX modules, but now that he’s using .NET this is no longer possible.
Here’s some C# code that can be used from LISP (once it’s been NETLOADed, of course) to get a list of the .NET assemblies currently loaded into AutoCAD’s AppDomain, helping with the decision on what to go ahead and import. The returned list contains dotted pairs of the module names along with their versions, which should also be handy when troubleshooting version-related problems.
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using System.Reflection;
using System;
namespace LoadedAssemblies
{
public class Commands
{
[LispFunction("GetAssemblies")]
public ResultBuffer GetLoadedAssemblies(ResultBuffer rb)
{
// Get the list of loaded assemblies
Assembly[] assems = AppDomain.CurrentDomain.GetAssemblies();
// A ResultBuffer to populate and return
ResultBuffer res = new ResultBuffer();
// List the assemblies in the current application domain.
const string start = "Version=";
foreach (Assembly assem in assems)
{
// We want the name and version of each assembly
string dllname = assem.ManifestModule.Name;
string version = assem.FullName;
// If our assembly name includes version info...
if (version.Contains(start))
{
// Get the string starting with the version number
version =
version.Substring(
version.IndexOf(start) + start.Length
);
// Strip off anything after (and including) the comma
version =
version.Remove(version.IndexOf(','));
}
else
version = "";
// Add a dotted pair of the name with the version
res.Add(new TypedValue((int)LispDataType.ListBegin));
res.Add(new TypedValue((int)LispDataType.Text, dllname));
res.Add(new TypedValue((int)LispDataType.Text, version));
res.Add(new TypedValue((int)LispDataType.DottedPair));
}
return res;
}
}
}
Let’s see what happens when we run this from the command-line (with the output reformatted to show the list contents better):
Command: (getassemblies)
(("mscorlib.dll" . "2.0.0.0")
("AcdbMgd.dll" . "18.0.0.0")
("msvcm90.dll" . "9.0.30729.4148")
("System.dll" . "2.0.0.0")
("System.Xml.dll" . "2.0.0.0")
("System.Drawing.dll" . "2.0.0.0")
("PresentationFramework.dll" . "3.0.0.0")
("WindowsBase.dll" . "3.0.0.0")
("PresentationCore.dll" . "3.0.0.0")
("AdWindowsInterop.dll" . "0.0.0.0")
("AdWindows.dll" . "2.1.0.0")
("acmgd.dll" . "18.0.0.0")
("System.Configuration.dll" . "2.0.0.0")
("AcWindows.dll" . "18.0.0.0")
("System.Core.dll" . "3.5.0.0")
("AcWindows.resources.dll" . "18.0.0.0")
("AcCui.dll" . "18.0.0.0")
("AliasUnderlayRibbionUI.dll" . "1.0.0.0")
("ADNPlugin-OffsetInXref.dll" . "1.0.1.0")
("MyApplication.dll" . "1.0.3695.27974")
("<Unknown>" . "0.0.0.0")
("AliasRibbonUI.dll" . "18.0.55.1")
("PresentationFramework.Aero.dll" . "3.0.0.0")
("ManagedMC3.dll" . "2.20.0.0")
("System.Management.dll" . "2.0.0.0")
("AcLayer.dll" . "18.0.0.0")
("System.Windows.Forms.dll" . "2.0.0.0")
("AcLayer.resources.dll" . "18.0.0.0")
("System.Web.Services.dll" . "2.0.0.0")
("WindowsFormsIntegration.dll" . "3.0.0.0")
("<Unknown>" . "2.1.0.0"))
Thanks again, Jim, for this very useful little application. :-)