动态加载 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 插件开发的更多信息。
我正在处理一个项目,我必须弄清楚目标计算机上安装的 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 插件开发的更多信息。