1

for an auto update logic, I'd like to load a specific version of an assembly. I'm trying to use Assembly.Load method with either assemlyName string or AssemblyName class parameter. For example:

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

This code happily loads v1.0.0.0 of MyAssembly, which I've referenced normally.

The challenge here is to load a specific version of MyAssembly. My strategy for this has been to wire up AssemblyResolve event (making sure that assembly loading doesn't happen in main method since I've read that it doesn't work there). Then I'd be debugging thru and manually changing the version number of the string from "1.0.0.0" to "2.0.0.0", expecting AssemblyResolve to fire. Surprisingly the CLR happily loads version 1.0.0.0 and fires no events.

Does anyone have a simple and working way to load a specific version of an assembly at runtime?

EDIT:

Thanks for all the answers so far. I haven't gotten it working yet the way I'd like, so your help is still needed. What I did get working was the AssemlyResolve event, like this:

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 

It seems that I have 18 assemblies loaded coming this piece of code, and to my surprise Class1 Type's Assembly (called MyAssembly, version 1.0.0.0) has already been loaded. That Assembly is referenced in visual studio normally.

When I manually load v1.1.0.0 of the same assembly, I need to use a little trick, a misspelled name, with underscore to get the AssemblyResolve event firing. Then it loads and I have 19 assemblies loaded, MyAssembly two times, once for v1.0.0.0 and once for 1.1.0.0. All fine except using 1.1.0.0. is a pain, I need to use reflection for that.

What I'd like to have to have direct access to v1.1 (the manually loaded one) of MyAssembly with this command:

var class1 = new Class1(); 

But now CLR gives me v1.0, the one referenced in visual studio.

How to fix this?

EDIT 2:

This question ended up morping too much, I made a compacter question here: New instance from a manually loaded assembly

9
  • Maybe 2.0.0.0 is not available in GAC? So you only have 1.0.0.0 and a fallback happens? Commented Nov 12, 2014 at 13:55
  • 1
    It will load whatever assembly it finds on disk if it is not stored in the GAC. But will insist on an exact match, unless you use a publisher policy or a binding redirect to convince it that the wrong version is okay. Commented Nov 12, 2014 at 13:59
  • Hans, honestly v 2.0.0.0 does not even exist yet so it definitely does not load an exact match. :) Commented Nov 12, 2014 at 14:07
  • 2
    No, the match is checked after it loaded the assembly. Commented Nov 12, 2014 at 14:15
  • 1
    @Pompair: So you do have another version already loaded. Test what happens with an assembly that you don't have a Visual Studio reference to. Commented Nov 12, 2014 at 14:29

2 Answers 2

1

you can load a specific assembly from a specific directory using:

Assembly.LoadFrom(string path) 

and learn more about it here

now, you said it's your assembly, then if you decided to use reflection you can put it in a specific place (using to post-build for example to move it there) and in that way you don't have to change your code much. you can also investigate the location in order to know what files are there and load them and no loading writing the whole path hard-coded

Directory.GetFiles(string folderPath) 

and then

foreach(string curr in filePaths) { Assembly.LoadFrom(curr ) } 
Sign up to request clarification or add additional context in comments.

2 Comments

NIFN, this might be useful, however I want to implement selective autoupdate mechanism where I pull down dll's from cloud but only the dlls that are in the cloud. I'll have to think if your solution allows me to do this...
@NoIdeaFor Name could you have a look at this question please? stackoverflow.com/questions/67177542/…
0

You should check that there is no assembly already loaded with the same name as the one you want to load. That will prevent the loading of the second assembly.

If that isn't the case, you could use AssemblyResolve to get the assembly when .NET can't resolve it itself.

Here a small sample console app:

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

When you disable the two event handlers, you will see no assembly can be loaded. If you enable it, you will see it uses the assembly you provided.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.