动态加载 AutoCAD dll 时出现异常

Exception while loading AutoCAD dll dynamically

我正在处理一个项目,我必须弄清楚目标计算机上安装的 AutoCAD 版本。我们已经考虑了存在多个 AutoCAD 版本的可能性,因此,根据用户的选择,我们必须从该版本的 AutoCAD 动态加载所需的 DLL。首先,该程序会发现 AutoCAD 的可用版本并将其显示给用户。然后,在选择特定版本后,程序会将 (accoremgd.dll、acdbmgd.dll、acmgd.dll) 等 DLL 复制到程序目录。但是当我尝试动态加载那些 dll 时,它显示以下错误:

Could not load file or assembly 'accoremgd.dll' or one of its dependencies. The specified module could not be found.

堆栈跟踪:

at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark) at System.Reflection.Assembly.LoadFrom(String assemblyFile) at DynamicDLLAdd.Form1.btnLoad_Click(Object sender, EventArgs e) in e:\AutoCadOperations\Test.AutoCadLoad_Re\DynamicDLLAdd\Form1.cs:line 140

我动态加载文件的sub-routine是:

try
{
    string destFile = @Path.Combine(Environment.CurrentDirectory,"accoremgd.dll"); 
    if (!File.Exists(destFile))
        return;

    Assembly a = null;
    a = Assembly.LoadFrom(destFile);

    AppDomain.CurrentDomain.Load(a.GetName());
    MessageBox.Show("LOADED");
    Type classType = a.GetType("Autodesk.AutoCAD.ApplicationService.Document");
    object obj = Activator.CreateInstance(classType);
    MethodInfo mi = classType.GetMethod("Create");
    //rest of the code here
}
catch (Exception exp)
{
    MessageBox.Show(exp.Message);
    MessageBox.Show(exp.Source);
    MessageBox.Show(exp.StackTrace);
}

我认为问题可能与 dll 的依赖项有关。应该做什么?有没有可用的文件或文章?

更新: 该程序的目标框架是 4.0,平台目标是 Any CPU.

I 运行 fuselogvw.exe 并且我认为这可能是解决我的问题的一些线索。我不知道这里发生了什么,所以我添加了一张图片。如果澄清一下,那将是一个很大的帮助。

我认为,它的问题是未加载依赖项 dll。

检查以下可能性

1) 更改平台目标 (AnyCPU,86,64)

2) 复制的 dll (accoremgd.dll, acdbmgd.dll, acmgd.dll) 放入以下目录

-> C:\Windows\System32
-> C:\Windows\SysWOW64  

3) 更改 .net 框架

不应在您的 DLL 库中手动加载 AcMgd、AcCoreMgd 或 AcDbMgd,默认情况下,这些引用是在 AutoCAD 进程 (acad.exe) 上加载的(仅来自 acad.exe 文件夹)并且当你 NETLOAD 你的 DLL 库(即你的插件)时,它会自动 link。编译 DLL 库时,在 AutoCAD 参考上设置 Copy Local = FALSE。如果将其保留为 TRUE,AutoCAD 将出现意外行为。

此外,您不应在外部应用程序(即 Visual Studio 上的 .EXE 项目)上使用 AutoCAD 引用。事实上,这些引用是一个薄层,用于访问 C++ 中的实际实现(编译为 .ARX 动态库),并且只能在 acad.exe 的进程中工作。如果需要从外部应用程序调用 AutoCAD,可以使用 COM Automation 或 AutoCAD Console。 See this reply.

也就是说,从 AutoCAD 2012 开始,您可以使用 Autoloader mechanism。总之,您可以定义一个 PackageContents.xml 文件,该文件将根据您的客户拥有的 AutoCAD 版本定义要加载的 DLL 库。这是将插件加载到 AUtoCAD 中的最简单方法。

如果您仍然需要手动注册您的插件(DLL 库),您可以创建一个registry key for it, but it's a bit tricky due many AutoCAD versions of verticals (e.g. Civil 3D, Plant 3D, Map 3D, etc.). There is certain logic on the registry keys, check more here

Developer Center 上查看有关 AutoCAD 插件开发的更多信息。