Can not load managed assembly that is located in the same folder

417 views Asked by At

To recreate my production environment I created the following folder structure:

c:\TEST\tested.dll c:\TEST\tested\tools.dll

The tested.dll is compiled using the following App.config file:

  <?xml version="1.0" encoding="utf-8" ?>
  <configuration>
    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="tested"/>
      </assemblyBinding>
    </runtime>
  </configuration>

As far as I know the application should look for it's tools file in the subfolder. When I try to start the station I still get the error that the file was not found.

To give some context here is an example tested.dll source:

    namespace ConsoleApplication1
    {
        public static class Testable
        {
            public static tools.IToolAble usefultool = null;

            public static void initialisation()
            {
                if (usefultool == null) usefultool = new UsefulTest()
            }
        }

        public class UsefulTest : tools.IToolAble
        {
        }
    }

and an example tools.dll source:

    namespace tools
    {
        public interface IToolAble
        {
        }
    }

The code that crashes is my testcode that works like this:

    private CustomMock controller = new CustomMock();
    public void TestFixtureSetUp()
    {
        controller.LoadFrom(@"c:\TEST\tested.dll");

        //The next line crashes because tools assembly is needet but not found
        controller.InvokeInitialisation();
    }

What am I missing? Is the App.config correct?


EDIT:

The Answer below is correct, the path is only known once the correct dll can be chosen. So the other team has to add a new ResolveEventHandler before loading. Here is a simplified version of that:

    internal void AddResolveEventHandler(string assemblyname, string assemblylocation)
    {
        AppDomain.CurrentDomain.AssemblyResolve +=
        new ResolveEventHandler(
            (sender, args) =>
            {
                Assembly ret = null;
                if (
                    new AssemblyName(args.Name).Name == assemblyname && 
                    File.Exists(assemblylocation))
                {
                    ret = Assembly.LoadFrom(assemblylocation);
                }
                return ret;
            }
        );
    }
1

There are 1 answers

1
Hans Passant On BEST ANSWER

the tested.dll is compiled using the following App.config file

It needs to be an yourapp.exe.config file, not a .config file for the DLL. The CLR only ever looks for a .config file associated with the main process.

And watch out for app.vshost.exe.config, required when you debug with the hosting process enabled.

And watch out when using unit test runners, another .exe file

Do consider if this is actually worth the trouble. Your user won't care where the DLL is located.