Assembly.Load dons';t加载它的特定版本

本文关键字:版本 加载 dons Load Assembly | 更新日期: 2023-09-27 18:30:05

对于自动更新逻辑,我想加载程序集的特定版本。我正在尝试将Assembly.Load方法与assemlyName字符串或AssemblyName类参数一起使用。例如:

string aname = "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
var asm = Assembly.Load(aname);

这段代码愉快地加载了MyAssembly的0.0.0版本,我已经正常引用了它。

这里的挑战是加载MyAssembly特定版本。我的策略是连接AssemblyResolve事件(确保程序集加载不会在main方法中发生,因为我读到它在那里不起作用)。然后,我将通过并手动调试,将字符串的版本号从"1.0.0.0"更改为"2.0.0.0",期望AssemblyResolve启动。令人惊讶的是,CLR愉快地加载了1.0.0.0版本,并且没有触发任何事件。

有人能在运行时加载程序集的特定版本吗?

编辑:

感谢到目前为止所有的答案。我还没有按照我想要的方式工作,所以仍然需要你的帮助。我所做的是AssetyResolve事件,就像这样:

int loadedAssemblies = getAsmCount(); // = 18
// LOAD V1.1 *UNREFERENCED*
var asm1_1 = Assembly.Load("_MyAssembly"); // AssemblyResolve fires behind the scene...
loadedAssemblies = getAsmCount(); // = 19
// USE V1.0 *REFERENCED IN VS SOLUTION*
// Note: seems that this Type's assembly has already been loaded!
var asm1_0 = new Class1().GetType().Assembly; 
loadedAssemblies = getAsmCount(); // = 19

在这段代码中,我似乎加载了18个程序集,令我惊讶的是,Class1类型的程序集(名为MyAssembly,1.0.0.0版本)已经加载。该程序集通常在visual studio中被引用。

当我手动加载同一程序集的v1.0.0版本时,我需要使用一个小技巧,一个拼写错误的名称,加下划线来触发AssemblyResolve事件。然后它加载了,我加载了19个程序集,MyAssembly加载了两次,一次用于v1.0.0,另一次用于1.1.0.0。除使用1.1.0.0外,一切正常。是一种痛苦,我需要反思。

我想用以下命令直接访问MyAssembly的v1.1(手动加载的版本):

var class1 = new Class1();

但现在CLR给了我v1.0版本,这是visualstudio中引用的版本。

如何解决此问题?

编辑2:

这个问题最终解决得太多了,我在这里提出了一个更紧凑的问题:手动加载的程序集的新实例

Assembly.Load dons';t加载它的特定版本

您可以使用从特定目录加载特定程序集

Assembly.LoadFrom(string path)

并在这里了解更多信息

现在,你说这是你的程序集,那么如果你决定使用反射,你可以把它放在一个特定的地方(例如,用来后期构建,把它移到那里),这样你就不必对代码做太多更改。你也可以调查位置,以了解那里有什么文件,并加载它们,而不加载写入整个路径硬编码

Directory.GetFiles(string folderPath)

然后

foreach(string curr in filePaths)
{
   Assembly.LoadFrom(curr )
}

您应该检查是否已经加载了与要加载的程序集同名的程序集。这将防止装载第二个组件。

如果不是这样的话,当.NET无法自行解析程序集时,可以使用AssemblyResolve来获取该程序集。

这里有一个小示例控制台应用程序:

static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad;
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    string aname = "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
    var asm = Assembly.Load(aname);
    Console.ReadKey();
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    Console.WriteLine("Resolving " + args.Name);
    return Assembly.LoadFrom(@"C:'path'MyAssembly.6.0.dll");
}
static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
    Console.WriteLine("Loading " + args.LoadedAssembly.FullName);
}

当您禁用这两个事件处理程序时,您将看到无法加载任何程序集。如果启用它,您将看到它使用您提供的程序集。