Could not load file or assembly

12,814

Things always get tricky with .net if you are attempting to load from a folder that isn't within the folder or subfolders of your application EXE's location. I would recommend trying two things. First, use the <probing> attribute to specify where to look for your custom DLL, see this answer, rather than the way you are doing it.

Second, if that doesn't work, try using the AppDomain.AssemblyResolve event instead of using your config file. You can then load your assembly from wherever you want.

Edit: Jay Walker points out that ..NET 4 and higher have changed AssemblyResolve so that if the DLL is one that isn't in the custom folder, return null to retain the default behavior.

Here's some sample code for AssemblyResolve:

Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    if (args.Name == THE_DLL_I_WANT_TO_CUSTOM_LOAD)
    {
        // Load from our custom path
        string finalPath = null;
        try
        {
            finalPath = MyCustomPath + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
            return Assembly.LoadFrom(finalPath);
        }
        catch ()
        {
        }
    }

    // Not our custom, use the default loading
    return null;
}
Share:
12,814
Jason
Author by

Jason

Updated on June 04, 2022

Comments

  • Jason
    Jason almost 2 years

    I have a simple executable that i would like to use a dll in. I have added it as a reference. I created an app.config file because the dll is not ultimately going to be in the executable directory. If i execute my program from the IDE, everything is fine, b/c the the dll is copied it locally, but as soon as i pull my executable out it crashes. My fusion log implies it that it cannot find the file specified.

    My Main() method:

    AppDomain currentDomain = AppDomain.CurrentDomain;
    currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
    
    Assembly assembly = null;
    String dllLocation = @"C:\BMS_ACTD\bin\DX\Tools\BmsReplayAnalysis.dll";
    IToolsInterface myProgram = null; //from ToolsInterface.dll
    try
    {
        assembly = Assembly.LoadFrom(dllLocation);
    }
    catch
    {
    }
    
    foreach (Type myType in assembly.GetTypes())
    {
        if (myType.GetInterface(typeof(IToolsInterface).FullName) != null)
        {
            myProgram = (IToolsInterface)assembly.CreateInstance(myType.Namespace + "." + myType.Name, true);
            myProgram.RunTool();
            break;
        }
    }
    

    Here is my config file:

    <runtime>
        <dependentAssembly>
            <assemblyIdentity name="ToolsInterface" publicKeyToken="null" culture="neutral" />
            <codeBase version="1.0.0.0" href="file://C:/BMS_ACTD/bin/DX/Globals/ToolsInterface.dll"/>
        </dependentAssembly>
    </runtime>
    

    I don't want to have to worry about doing strong naming. I will only have 1 version of that dll, and that is all i care about.

    here is the excerpt from the fusionlog:

    The operation failed.
    Bind result: hr = 0x80070002. The system cannot find the file specified.
    
    Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
    Running under executable  C:\Users\greenj\Desktop\BmsReplayLauncher.exe
    --- A detailed error log follows. 
    
    === Pre-bind state information ===
    LOG: User = BMS-JMGREEN\greenj
    LOG: DisplayName = ToolsInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
     (Fully-specified)
    LOG: Appbase = file:///C:/Users/greenj/Desktop/
    LOG: Initial PrivatePath = NULL
    LOG: Dynamic Base = NULL
    LOG: Cache Base = NULL
    LOG: AppName = BmsReplayLauncher.exe
    Calling assembly : BmsReplayLauncher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
    ===
    LOG: This bind starts in default load context.
    LOG: Using application configuration file: C:\Users\greenj\Desktop\BmsReplayLauncher.exe.Config
    LOG: Using host configuration file: 
    LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
    LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
    LOG: Attempting download of new URL file:///C:/Users/greenj/Desktop/ToolsInterface.DLL.
    LOG: Attempting download of new URL file:///C:/Users/greenj/Desktop/ToolsInterface/ToolsInterface.DLL.
    LOG: Attempting download of new URL file:///C:/Users/greenj/Desktop/ToolsInterface.EXE.
    LOG: Attempting download of new URL file:///C:/Users/greenj/Desktop/ToolsInterface/ToolsInterface.EXE.
    LOG: All probing URLs attempted and failed.