Search code examples
c#.netdllassembly-loadingfuslogvw

Assembly fails to load, no fusion log error


I've got a very minimal console app which just tries to print out the value of an enum from a referenced assembly. Let's call the assembly "VendorAssembly.DDK.dll", and say it defines "Vendor.Namespace". Here's my anonymised test code. IntervalType is just an enum.

using Vendor.Namespace;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            IntervalType h = IntervalType.Hours;

            Console.WriteLine($"{h}");
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}

It compiles fine.

But when I try to run it, an exception immediately occurs (before the Main() method is actually entered) which says:

System.IO.FileNotFoundException was unhandled Message: An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll Additional information: Could not load file or assembly 'VendorAssembly.DDK.dll' or one of its dependencies. The specified module could not be found.

Even though I've tried to run this app several times, fuslogvw.exe doesn't list any bind errors for it. With fuslogvw.exe set to "Log all binds to disk" with a custom log path enabled, searching the custom fusion log folder shows one binding event, which was apparently successful?

*** Assembly Binder Log Entry  (19/01/2018 @ 6:09:45 PM) ***

The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\SVN\redacted\ConsoleApplication1\bin\Debug\ConsoleApplication1.vshost.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = VendorAssembly.DDK, Version=6.77.6580.1, Culture=neutral, PublicKeyToken=9e16b9dd55e2cd53
 (Fully-specified)
LOG: Appbase = file:///C:/SVN/redacted/ConsoleApplication1/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = ConsoleApplication1.vshost.exe
Calling assembly : ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\SVN\redacted\ConsoleApplication1\bin\Debug\ConsoleApplication1.vshost.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Publisher policy file is found at C:\WINDOWS\Microsoft.Net\assembly\GAC_64\policy.6.77.VendorAssembly.DDK\v4.0_6.77.6580.1__9e16b9dd55e2cd53\policy.6.77.VendorAssembly.DDK.config.
LOG: Publisher policy file redirect is found: 6.77.6580.1 redirected to 6.77.6580.1.
LOG: ProcessorArchitecture is locked to AMD64.
LOG: Post-policy reference: VendorAssembly.DDK, Version=6.77.6580.1, Culture=neutral, PublicKeyToken=9e16b9dd55e2cd53, processorArchitecture=AMD64
LOG: Found assembly by looking in the GAC.
LOG: Binding succeeds. Returns assembly from C:\WINDOWS\Microsoft.Net\assembly\GAC_64\VendorAssembly.DDK\v4.0_6.77.6580.1__9e16b9dd55e2cd53\VendorAssembly.DDK.dll.
LOG: Assembly is loaded in default load context.

The VendorAssembly.DDK.DLL is a managed wrapper which calls into unmanaged C++ code. Looking at VendorAssembly.DDK.dll in the Visual Studio Assembly Explorer says that it references mscorlib, System, System.Configuration.Install, System.Data, System.Xml, and Kernel32.dll. I have added all the listed .NET assemblies as references to the Console application also.

My console app targets the x64 platform and .NET 4.5.1, which exactly matches the metadata on VendorAssembly.DDK.dll.

What do I need to do to get this assembly to load properly?

Why doesn't fuslogvw show what's going wrong?


Solution

  • The assembly load failure was caused by unmanaged (C++ DLL) dependencies of VendorAssembly.DDK.dll which were not visible in Visual Studio's Assembly Explorer, are not mentioned in the Fusion logs displayed by fuslogvw.exe, and are not detailed in the .NET reflection exception stack trace.

    I used Dependency Walker to identify and analyse the unmanaged dependencies.

    Another useful tool for identifying what's missing with unmanaged dependencies is Sysinternals Process Monitor (Procmon) which can list the names of missing unmanaged dependencies at runtime when the process fails to load.