1

Background
First of all, I did look elsewhere for a solution and found this solution, but this does not solve my issue.

I have an assembly referenced in my main project in Visual Studio, but I need to load it from outside my project, not in a sub-folder. I can load the assembly with the call...

System.Reflection.Assembly.LoadFrom(myExternalAssemblyPath);

...but the program will not run and gives me the following error:

FileNotFoundException was unhandled

Could not load file or assembly 'MyAssembly, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

I have no calls to the assembly before the call to load it, but the program still expects, even before it even enters the Main function apparently, that the DLL be in the program's folder.

Quesiton:
How do I get my program to still reference this in Visual Studio, but load it from a different location when actually running the program? Is there a directive I need to specify somewhere to tell the program to wait to load it? Is there some other solution?

NOTE: I do not want to add the folder and DLL to the PATH variable. That is not a viable solution.

Community
  • 1
  • 1
Mike Webb
  • 8,855
  • 18
  • 78
  • 111
  • If it expects it before the Main method, then: don't use that assembly from the Main method (JIT happens before the method starts) - however, what you describe is going to fight normal assembly probing rules - is it really worth it? – Marc Gravell Jun 01 '12 at 17:31
  • @MarcGravell: Yes, I need to do this because we will be eventually referencing this same library in other similar programs. – Mike Webb Jun 01 '12 at 18:44
  • and let me ask the question: "so?" you are allowed multiple copies of a file - it makes deployment much much easier. Alternatively, consider the GAC. .net design expects either local (copy per application) libraries, or central shared libraries in the GAC. – Marc Gravell Jun 01 '12 at 19:05
  • @MarcGravell: I'll look into the GAC. I'll have to discuss it my clients, but in the end I am bound by how they want this implemented. – Mike Webb Jun 01 '12 at 19:09
  • that's like me telling a plumber how I want pipes to work. It is entirely possible that they are making an unqualified and incorrect request. An appropriate response would be "that might be possible, but is is very unusual and will require n hours at m rate; or we can use the GAC, the way .NET is designed to handle shared dlls - that option is free" – Marc Gravell Jun 01 '12 at 19:14
  • @MarcGravel: I tried your suggestion about Main and it worked. If you want to post an answer I will try to distribute acceptance between you and Wiktor. I will definitely up-vote it. Whether you post an answer or not, thanks for the responses and the help. – Mike Webb Jun 01 '12 at 19:16
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/12044/discussion-between-mike-webb-and-marc-gravell) – Mike Webb Jun 01 '12 at 19:19

1 Answers1

3

The trick is to implement the AssemblyResolve event on your application domain.

http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve.aspx

This is where you help the runtime to locate assemblies which it tries to load and cannot find using the default searching strategy. This should be straightforward, the runtime will call your handler for each missing assembly and you just have to load it by yourself from the custom path and return from the handler.

An important point to remember: in .NET the JIT processes methods (into native code) fully before they are invoked. If your Main method uses any types or methods from the assembly you are trying to load, it won't get as far as executing Main. Consequently, Main should only setup the assembly-loading. All other code (especially code relating to the assembly in question) must be moved to another method, so it gets JIT-ted separately.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106