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

Dependency checker tool

1 REPLY 1
Reply
Message 1 of 2
mterwoord
579 Views, 1 Reply

Dependency checker tool

Our company has an internal tool to check for all referenced assemblies of a given .NET Assembly. This is very handy for figuring out what to send to the customer, etc.

This works great for normal .net assemblies (both .dll and .exe).

 

When I use this tool on an AutoCAD project's .dll file, I get a FileNotFoundException on acdbmgd.dll. This happens even when copying that dll over to the directory of the source .dll file.

Is there anything special about the autocad .dll files?

 

1 REPLY 1
Message 2 of 2
khoa.ho
in reply to: mterwoord

Hi,

 

You can follow my previous post with alex_b on Nov 2 (Is dll a AutoCAD plug-in?). Use Mono.Cecil library to get reflection of unmanaged AutoCAD assemblies (acdbmgd.dll, acmgd.dll, accoremgd.dll...).

 

Use Mono.Collections.Generic.Collection<ModuleDefinition> modules = assembly.Modules; to load unmanaged referenced assemblies.

 

Here is the code to read an AutoCAD plug-in:

 

// Copyright by Khoa Ho

using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using Mono.Cecil; namespace AcadReflection { class ManagedAssembly { static void Main1(string[] args) { try { string dllPath = @"C:\Program Files\Autodesk\AutoCAD Plant 3D 2013 - English\AcCalcUi.dll"; string output = GetAutocadPluginDetails(dllPath); Console.WriteLine(output); } catch (BadImageFormatException ex) { Console.WriteLine(ex.Message + "\n" + ex.StackTrace); } } #region Reflection with .NET framework public static string GetAutocadPluginDetails(string dllPath) { try { if (string.IsNullOrEmpty(dllPath)) return string.Empty; string dllName = Path.GetFileName(dllPath); string acadVersion = GetAutocadPluginVersion(dllPath); List<string> acadCommands = GetAllAutocadCommands(dllPath); string message = string.IsNullOrEmpty(acadVersion) ? "File " + dllName + " is not an AutoCAD plug-in" : "File " + dllName + " is an AutoCAD plug-in that supports AutoCAD " + acadVersion + (acadCommands.Count == 0 ? string.Empty : "\nFound commands in this plug-in: " + String.Join(", ", acadCommands.ToArray())); return message; } catch (BadImageFormatException ex) { throw; } } private static string GetAutocadVersion(AssemblyName assemblyName) { var AutoCADVersion = new Dictionary<string, string> { { "15.0", "2000" }, { "15.1", "2000i" }, { "15.6", "2002" }, { "16.0", "2004" }, { "16.1", "2005" }, { "16.2", "2006" }, { "17.0", "2007" }, { "17.1", "2008" }, { "17.2", "2009" }, { "18.0", "2010" }, { "18.1", "2011" }, { "18.2", "2012" }, { "19.0", "2013" } }; string acadVersion = string.Empty; string version = assemblyName.Version.Major + "." + assemblyName.Version.Minor; if (AutoCADVersion.ContainsKey(version)) { acadVersion = AutoCADVersion[version]; } return acadVersion; } // Get the AutoCAD version of a given DLL file, // returns empty string if it is not an AutoCAD plug-in public static string GetAutocadPluginVersion(string dllPath) { string acadVersion = string.Empty; // Indicate the most common DLL name referencing in an AutoCAD plug-in const string dllName = "acdbmgd"; // Loads an assembly into the reflection-only context, given its path try { Assembly assembly = Assembly.ReflectionOnlyLoadFrom(dllPath); AssemblyName loadedAssemblyName = assembly.GetName(); // Check if this assembly is the defined dllName if (loadedAssemblyName.Name.ToLower() == dllName.ToLower()) { acadVersion = GetAutocadVersion(loadedAssemblyName); } else // this assembly is not acdbmgd.dll { AssemblyName[] assemblyNames = assembly.GetReferencedAssemblies(); foreach (AssemblyName assemblyName in assemblyNames) { string name = assemblyName.Name; if (name.ToLower() == dllName.ToLower()) { acadVersion = GetAutocadVersion(assemblyName); break; } } } } catch (Exception ex) { throw; } return acadVersion; } // Retrieve all AutoCAD commands from a given DLL plug-in file public static List<string> GetAllAutocadCommandsNET(string dllPath) { var commandList = new List<string>(); try { AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomainOnReflectionOnlyAssemblyResolve; // Loads the contents of an assembly file Assembly assembly = Assembly.ReflectionOnlyLoadFrom(dllPath); // Get all types/classes in this assembly Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException typeException) { types = typeException.Types; } foreach (Type type in types) { if (type == null) continue; // Get all methods in this class MethodInfo[] methodInfos = type.GetMethods(); foreach (MethodInfo methodInfo in methodInfos) { try { // Get AutoCAD command's attribute //object[] attributes = methodInfo.GetCustomAttributes(false); IList<CustomAttributeData> attributeDataList = CustomAttributeData.GetCustomAttributes(methodInfo); foreach (CustomAttributeData customAttributeData in attributeDataList) { if (customAttributeData.GetType().Name == "CommandMethodAttribute") { // Get AutoCAD command name string commandName = ""; // ((CommandMethodAttribute)attributes[0]).GlobalName; commandList.Add(commandName); } } } catch (FileNotFoundException fileException) { //throw; } } } } catch (BadImageFormatException ex) { throw; } return commandList; } private static Assembly CurrentDomainOnReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args) { return Assembly.ReflectionOnlyLoad(args.Name); } #endregion #region Reflection with Mono.Cecil public static List<string> GetAllAutocadCommands(string dllPath, string acadCommandAttribute = "CommandMethodAttribute") { var commandList = new List<string>(); try { AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(dllPath); // Get all program modules Mono.Collections.Generic.Collection<ModuleDefinition> modules = assembly.Modules; foreach (ModuleDefinition module in modules) { // Get all types/classes which are declared in the module Mono.Collections.Generic.Collection<TypeDefinition> types = module.Types; foreach (TypeDefinition type in types) { if (type == null) continue; // Get all methods in this class Mono.Collections.Generic.Collection<MethodDefinition> methods = type.Methods; // Get all custom attributes for this method foreach (MethodDefinition method in methods) { Mono.Collections.Generic.Collection<CustomAttribute> attributes = method.CustomAttributes; // Check if the attribute is what we want foreach (CustomAttribute attribute in attributes) { if (attribute.Constructor.ToString().Contains(acadCommandAttribute)) { Byte[] bytes = attribute.GetBlob(); string command = ASCIIEncoding.ASCII.GetString(bytes); command = ReplaceNonPrintableCharacters(command); commandList.Add(command); } } } } } } catch (Exception ex) { } return commandList; } static string ReplaceNonPrintableCharacters(string s) { var result = new StringBuilder(); for (int i = 0; i < s.Length; i++) { char c = s[i]; byte b = (byte)c; if (b >= 32) result.Append(c); } return result.ToString(); } #endregion } }

 

-Khoa

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