gpt4 book ai didi

c# - 在运行时加载程序集,Autocad 插件示例

转载 作者:太空宇宙 更新时间:2023-11-03 10:25:50 25 4
gpt4 key购买 nike

在这个主题上花费了数小时(以及访问了数十页)后,我不得不寻求帮助。我看过很多关于这个主题的帖子,但我无法解决遇到的问题。

基本上,我想做的事情非常简单:将程序集从我的文件夹加载到应用程序。


这是一个简短的问题(所有其他细节在其余文本中解释)我想使用 Assembly.LoadFrom 方法加载我的程序集(项目引用了相同的程序集文件,但 CopyLocal: false),但是尽管在调用使用它的方法时加载了程序集,但程序会尝试从默认位置加载程序集。如果找到,则加载 2 个相同的程序集,程序使用最后一个,如果未找到,则引发 FileNotFoundException。但是,当我在 Autocad 插件中使用相同的想法时,尽管找不到文件,但一切正常并且不会引发异常。


我有两个简单项目的测试解决方案:TestExe(控制台应用程序)和 TestDll(dll 库)。我想在 TestExe 中使用 TestDll 中的类型,所以我添加了对 TestDll 的引用(我不是在引用 TestDll 项目,而是在指定位置引用文件),但我想在运行时手动加载 TestDll。为什么需要这样做在文本末尾用 Autocad 示例进行了解释。

据我了解,Assembly.LoadFrom 方法可用于此目的。所以基本的想法是:在 TestExe 中的方法使用它之前加载 TestDll,所以当调用方法时我们已经加载了程序集。这样,无论引用的 dll 是否存在于默认目录中,我们都已经加载了程序集并将使用它。

来自 MSDN:

If an assembly with the same identity is already loaded, LoadFrom returns the loaded assembly even if a different path was specified.

所以我明白,如果我加载一次 dll,同一程序集(也来自其他位置)的每次下一次加载都会知道它已经被添加,所以第一个将被使用。


项目:TestExe

//File: Program.cs
using System;
namespace TestExe
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new ClassExe().ExeMethod());
}
}
}
//File: ClassExe.cs
namespace TestExe
{
class ClassExe
{
public string ExeMethod()
{
return new TestDll.ClassDll().DllMethod();
}
}
}

项目测试Dll

using System.Reflection;

namespace TestDll
{
public class ClassDll
{
public string DllMethod()
{
return Assembly.GetExecutingAssembly().Location;
}
}
}

如您所见,任务很简单:显示被调用程序集的位置。

假设 TestDll.dll 被复制到应用程序文件夹 Extern\TestDll.dll。

如果我在 TestExe 项目中设置对 TestDll 的引用的属性 CopyLocal: false,程序将失败并出现 FileNotFoundException。 (1) 是否因为程序集只在默认目录(应用程序目录和TestDll\TestDll.dll)中搜索?

然后我尝试在使用它之前手动加载程序集:

static void Main(string[] args)
{
Assembly.LoadFrom(@"Extern\TestDll.dll");
Console.WriteLine(new ClassExe().ExeMethod());
}

但是我得到了同样的 FileNotFoundException,虽然 TestDll 已经加载 enter image description here

当我设置属性 CopyLocal: true 时,程序运行。但是,它会从默认位置再次加载 TestDll.dll,并忽略已加载的程序集。 enter image description here

我管理程序按我想要的方式工作(使用程序集 Extern\TestDll.dll)的唯一方法是使用 AppDomain.AssemblyResolve 事件。


我有 Autocad 插件,它使用来自不同解决方案的 10 个不同的 dll。所以我有 plugin.dll,它在 Documents 文件夹中引用 10 个 dll 文件,并设置 CopyLocal: true。但是,当部署给客户时,我只在应用程序文件夹中保留 plugin.dll,所有其他 dll 都在 Libraries 子目录中。在插件类的静态构造函数中,我将 Assembly.LoadFrom 从 Libraries 子目录加载,一切正常。

抱歉发了这么长的帖子,但我想详细解释一下。

感谢您的任何反馈:)

最佳答案

您可以通过检查程序集的加载上下文来尝试。 Here是一个例子,here是一篇文章。

基本原理是 AutoCad 在运行 acad.exe 进程的同一 AppDomain 中加载其程序集和插件程序集,因此它们对加载的所有其他程序集可见,因为它们是插件 dll 的引用。但是当你在 acad 进程中加载​​一个 dll 时,它对 .exe 是不可见的,反之亦然——它们都在不同的 app domains 中运行。并且看不到对方。

关于c# - 在运行时加载程序集,Autocad 插件示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31611887/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com