Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

After Handling AssemblyResolve Event Still getting Exception FileNotFound

I have handled the AssemblyResolve-event but I still get a FileNotFoundException. I have subscribed to the event in the type initializer and call the Assembly.LoadFrom method in the Main-method:

class Program
{
    static Program()
    {
        AppDomain.CurrentDomain.AssemblyResolve+=new ResolveEventHandler(DeployAssemblyHandler);
    }

    static void Main(string[] args)
    {      
        try
        {
            System.Reflection.Assembly asm=Assembly.LoadFrom("AxInterop.SHDocVw.dll");            
        }
        catch(Exception)
        {
        }
    }

    public static System.Reflection.Assembly DeployAssemblyHandler(object sender,ResolveEventArgs args)
    {            
        Assembly asm = null;
        string asmName = new AssemblyName(args.Name).Name;

        string deployAssemblyDirPath = ""; // Common.AppUtil.InstallDir + AppUtil.DeployedAssemblyDir;

        string[] deployDirectories = Directory.GetDirectories(deployAssemblyDirPath);            

        foreach(string deploy in deployDirectories)
        {
            try
            {
                asm = Assembly.LoadFrom(deploy + "\\" + asmName);
                break;
            }
            catch (Exception ex) { }
        }                   
        return asm;
    }
}
like image 324
Numan Hanif Avatar asked Nov 23 '25 05:11

Numan Hanif


2 Answers

I had the similar problem and ended with using a new AppDomain AND (important!) setting the PrivateBinPath property. The good thing about another AppDomain is that you can unload the assembly if you do not longer need it. The (my) sample code is:

  public class ProxyDomain : MarshalByRefObject
  {
      public bool TestAssembly(string assemblyPath)
      {
         Assembly testDLL = Assembly.LoadFile(assemblyPath);
         //do whatever you need 

         return true;
      }
   }

 AppDomainSetup ads = new AppDomainSetup();
 ads.PrivateBinPath = Path.GetDirectoryName("C:\\some.dll");
 AppDomain ad2 = AppDomain.CreateDomain("AD2", null, ads);
 ProxyDomain proxy = (ProxyDomain)ad2.CreateInstanceAndUnwrap(typeof(ProxyDomain).Assembly.FullName, typeof(ProxyDomain).FullName);
 bool isTdll = proxy.TestAssembly("C:\\some.dll");
 AppDomain.Unload(ad2);

EDIT: based on your comment you are just looking for the wrong event handler. In your case you should use an AppDomain.UnhandledException Event, because AssemblyResolve Event has different purpose.

like image 88
VladL Avatar answered Nov 25 '25 19:11

VladL


The problem is that AssemblyName.Name property returns the name of the assembly without the extension. You'll need to add ".dll" to the end of the path. (Warning: This will obviously break if the assembly's extension is not .dll)

like image 40
Kendall Frey Avatar answered Nov 25 '25 19:11

Kendall Frey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!