views:

38

answers:

2

We're currently developing an add-in for some software. We decided to develop in .NET, even though the application is written in some native language. Since there were some problems directly creating the external interface in .NET, we decided to build a bridge DLL in C++/CLI, which does some basic initialization and then loads our managed assembly and creates a user control from that.

In an add-in .ini file, the C++/CLI DLL is referenced by name, so the application will load it from there. The .NET DLL, however, is just referenced from the C++/CLI DLL (as a managed reference), so the exported types are available. In this setup, howerver, the application crashes loading the .NET DLL.

We quickly found that we could just subscribe to the AppDomain.AssemblyResolve event to load the .NET assembly from the same directory where the C++/CLI DLL is, so the problem itself is solved.

The actual question is: Why doesn't the loader find the .NET DLL, even though it is in the same directory as the assembly referencing it? I always expected that loading assemblies will first look into the same directory, rather than just into the current working directory. Why does an executable find an assembly if it changes its working directory then? Or are things different if the CLR is invoked by loading a C++/CLI assembly (rather than a pure managed application)?

+3  A: 

I would recommend you to use fuslogvw.exe for analyzing problems of this kind:

Fuslogvw.exe and diagnosing .NET assembly binding issues

And, of course, the general purpose tool for analyzing problems with files not found:

Process Monitor

0xA3
Thanks, I'll have a look into Fuslogvw.exe. I am aware of Process Monitor and Process Explorer to examine these problems, but both don't tell me *why* it doesn't work as I'd expect.
OregonGhost
+1  A: 

The probing path for assemblies get to be a bit unpredictable when a unmanaged EXE starts the process. Just because it loaded a C++/CLI DLL, perhaps through LoadLibrary or SetDllDirectory, does not in any way affect the probing path for the CLR.

But that's just guessing. There is no need to guess when you look at the output produced by Fuslogvw.exe. It shows you exactly what is being probed and what policies are applied. You fix the problem with an app.exe.config file (probing element) or indeed by AssemblyResolve.

Hans Passant
As I already said in the other comment, I'll have a look into Fuslogvw.exe. Maybe the app.exe.config is a better solution, though I'm basically fine with AssemblyResolve.
OregonGhost
Well, just keep in mind that you customer can change the .config file but not your event handler.
Hans Passant
@Hans Passant: That's a point for the event handler. Note that in this case the customer will get the full source code, while the end users expect an installation package that Just Works[TM].
OregonGhost
Are you arguing that having to dig through thousands of lines of code is *better* than a configuration file?
Hans Passant