mardi 30 juin 2015

FileNotFound when return Types[] from loaded assembly via reflection

I am trying to load an addin assembly (placed at

D:\xyz\addin.dll

while my application is in

D:\MyApp\MyApp.exe

such way that addin file should not be locked so that new version of it can be copied again while application is running. For that i created new app domain and loaded common dll which contains AssembltLoader Class, and then called AssemblyLoader to load addin and get all types available in it. Dependencies of Addin dll are already placed in same folder. Now Getting types from addin dll works fine but when i

return assembly.GetTypes();

a very strange thing happens. it executes that line but on exit of that function it throws exception "d:\xyz\addin.dll" FileNotFound

public class ObjectLoader : IDisposable
{
    public Type[] GetAllTypesFromAssembly(string filePath)
    {
        AppDomainSetup setup = new AppDomainSetup();
        setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
        setup.ShadowCopyFiles = "true";
        Evidence adevidence = AppDomain.CurrentDomain.Evidence;

        AssemblyLoader asemblyLoader = null;

        AppDomain appDomain = AppDomain.CreateDomain(filePath, adevidence, setup);

        appDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);

        domains.Add(filePath, appDomain);
        object[] parms = { filePath };

        BindingFlags bindings = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public;
        try
        {
            asemblyLoader = (AssemblyLoader)appDomain.CreateInstanceFromAndUnwrap(
            setup.ApplicationBase +
            "Common.dll", "Common.AssemblyLoader", 
            true, bindings, null, parms, null, null, null
            );
        }
        catch (Exception ex)
        {
            throw ex; // new AssemblyLoadFailureException();
        }

        object types = null;
        if (asemblyLoader != null)
        {
            // On following line i am facing the error which occur on following line but when GetAllTypes exits. 
            types = asemblyLoader.GetAllTypes();
         }
         return (Type[])types;
     }
}

internal class AssemblyLoader : MarshalByRefObject, IDisposable
{
    private Assembly assembly = null;
    public object GetAllTypes()
    {
        BindingFlags flags = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public;
        object types = null;
        if (assembly != null)
        {
            try
            {
                // following line works fine and loads a type (it contains one class)
                types = assembly.GetTypes(); 
            }
            catch (Exception)
            {
                types = new ObjectLoadFailureException();
            }
        }
        else
        {
            types = new AssemblyNotLoadedException();
        }
        return types;
    }
}

Here is the exception detail:

System.IO.FileNotFoundException was unhandled
HResult=-2147024894
Message=Could not load file or assembly 'AddIn, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
  Source=mscorlib
  FileName=AddIn, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
  FusionLog==== Pre-bind state information ===
LOG: DisplayName = AddIn, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///D:/MyApp/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).

if i copy my addin.dll both in D:\xyz\ and D:\MyApp\ then there is no error. I cannot do that in runtime environment.





Aucun commentaire:

Enregistrer un commentaire