C# 组装。加载不';不要加载它的特定版本

C# 组装。加载不';不要加载它的特定版本,c#,C#,对于自动更新逻辑,我想加载程序集的特定版本。我正在尝试使用AssemblyName字符串或AssemblyName类参数的Assembly.Load方法。例如: string aname = "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"; var asm = Assembly.Load(aname); 这段代码愉快地加载了我通常引用的MyAssembly的v1.0.0.0 这里的挑战是加载MyAssemb

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

string aname = "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
var asm = Assembly.Load(aname);
这段代码愉快地加载了我通常引用的MyAssembly的v1.0.0.0

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

是否有人有一种简单有效的方法在运行时加载特定版本的程序集

编辑:

谢谢你迄今为止的所有答案。我还没有让它按我想要的方式工作,所以仍然需要你的帮助。我所做的是AssemlyResolve事件,如下所示:

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.1.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.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);
}

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

可能GAC中没有2.0.0.0?所以您只有1.0.0.0,并且发生了回退?如果它没有存储在GAC中,它将加载它在磁盘上找到的任何程序集。但将坚持精确匹配,除非您使用发布者策略或绑定重定向来说服它错误的版本是可以的。Hans,老实说,v 2.0.0.0甚至还不存在,所以它肯定不会加载精确匹配。:)否,在加载程序集后将检查匹配。@Pompair:因此您已经加载了另一个版本。测试没有Visual Studio对.NIFN的引用的程序集会发生什么情况,这可能很有用,但是我希望实现选择性自动更新机制,在该机制中,我从云中下拉dll,但只下拉云中的dll。我得考虑一下,如果你的解决方案允许我这么做…@noideaforname你能看看这个问题吗?