Delay Loading a DLL generates a FileNotFoundException when calling the dll.

Answered Delay Loading a DLL generates a FileNotFoundException when calling the dll.

  • lunedì 12 marzo 2012 19:35
     
     

    I have a native C++ application that I am adding a dll to.  This dll is mixed native/managed C++ code and is used to call a COTS dll that is all native C# code.

    The application can instantiate the class in my dll, and can run methods in the dll that do not access the COTS dll.  As soon as I call a method that references the base class in the COTS dll, I am getting an System.IO.FileNotFoundException: Could not load file or assembly 'P1CaptureCoreNet32'.

    Here the last few lines of the output from the debugger:

    'DgxCaptureApp.exe' (Managed (v4.0.30319)): Loaded 'c:\working\sw-dgx\Common\P1\Libraries\DgxP1Wrapper.dll', Symbols loaded.
    'DgxCaptureApp.exe': Loaded 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll', Cannot find or open the PDB file
    'DgxCaptureApp.exe': Loaded 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\diasymreader.dll', Cannot find or open the PDB file
    'DgxCaptureApp.exe': Loaded 'C:\Windows\assembly\NativeImages_v4.0.30319_32\System\ffc825af968e2afbdd0d894b475331f3\System.ni.dll', Cannot find or open the PDB file
    'DgxCaptureApp.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll'
    First-chance exception at 0x7512b9bc in DgxCaptureApp.exe: Microsoft C++ exception: EEFileLoadException at memory location 0x0018cbf8..
    First-chance exception at 0x7512b9bc in DgxCaptureApp.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000..
    Managed Debugging Assistant 'BindingFailure' has detected a problem in 'C:\working\sw-dgx\DgxCaptureApp\Debug\DgxCaptureApp.exe'.
    Additional Information: The assembly with display name 'P1CaptureCoreNet32' failed to load in the 'Anonymous' binding context of the AppDomain with ID 1. The cause of the failure was: System.IO.FileNotFoundException: Could not load file or assembly 'P1CaptureCoreNet32, Version=630.630.2.51425, Culture=neutral, PublicKeyToken=d6a5651e514a0383' or one of its dependencies. The system cannot find the file specified.

    The program '[142256] DgxCaptureApp.exe: Native' has exited with code 0 (0x0).
    The program '[142256] DgxCaptureApp.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).

    DgxCaptureApp.exe is my native application. (native C++, /noCLR)
    DgxP1Wrapper.dll is my wrapper dll.         (mixed C++ native/managed, /CLR)
    P1CaptureCoreNet32 is the COTS dll.         (managed C#)

    P1CaptureCoreNet32.dll is Delay Loaded Dlls in both my programs.
    In DgxPrWrapper project in added P1CaptureCoreNet32.dll to the References.

    I created a separate C++ managed app to test calling the COTS dll, and it works fine.

    Do I need to call LoadLibrary, and why can't it find the file when the path is specified in the project properties? 


    Writing software since 1969.


    • Modificato Zeft lunedì 12 marzo 2012 19:37
    •  

Tutte le risposte

  • lunedì 12 marzo 2012 19:51
     
     

    The path project properties tells VS where to look for tools at build time and isn't passed to the application. So if you want your application to find a DLL that isn't in your current system's path or the same directory as your application then you will need to do some modifications.

    First of all though, make sure that just copying the DLL into the same directory as the executable will stop this error from occuring.

    If it does then you need to modify the settings for the debugger. This is the environment that gets passed to the spawned application.

    Go to Project Properties->Configuration Properties->Debugging and in Environment set it to "PATH=%PATH%;<path to dll>" without the quotes and obviously replacing <path to dll> with the actual path to the DLL. Make sure Merge Environment is set to yes and then try again.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

  • lunedì 12 marzo 2012 19:59
     
     

    The full path to the file is already in the Debug / Environment PATH=, and Merge Environement is set to Yes.  I placed the dll in the Debug directory and now I get this error:

    An unhandled exception of type 'System.IO.FileLoadException' occurred in Unknown Module.

    Additional information: Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

    Any idea on what additional configuration information is needed?


    Writing software since 1969.


    • Modificato Zeft lunedì 12 marzo 2012 20:00
    •  
  • lunedì 12 marzo 2012 23:13
     
     

    My guess would be the supportedRuntime setting in the application configuration file.

    The other option is the file which you are trying to load, if you can rebuild it with VS2010 or get a version built with VS2010.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

  • martedì 13 marzo 2012 12:50
     
     

    Unfortunately, the file I am trying to load is a package from another company, and I do not have the source code, and they have not supplied any information on their build configuration.

    I have written a test C++ application which successfully loads and runs the package.  I do not know what configuation is different in my test app, and my full product app.

    Is there a tool or a way to display the setting that is in error?


    Writing software since 1969.

  • martedì 13 marzo 2012 13:12
     
     

    So, I added a app.config file:

    <?xml version="1.0"?>
    <configuration>
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

    And I still get this error:

    An unhandled exception of type 'System.IO.FileLoadException' occurred in Unknown Module.

    Additional information: Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

    What additional configuration is needed?


    Writing software since 1969.



    • Modificato Zeft martedì 13 marzo 2012 13:13
    • Modificato Zeft martedì 13 marzo 2012 15:09
    •  
  • martedì 13 marzo 2012 15:49
     
     

    Well since your v4 assembly is loading first, the v4 runtime is implied. You have to also put in an entry for version="v2.0.50727" which the error message is telling you that it can't load because the currently loaded version of the .NET framework (which is v4 as the error is telling you) can't load an object compiled agains the v2 runtime into the v4 runtime without extra configuration. So you also need to allow the v2 framework to load.

    But I would still say it is easier to rebuild this particular object with VS2010 so that is built against .NET v4.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

  • mercoledì 14 marzo 2012 13:37
     
     

    I modified the app.config file to include <supportedRuntime version="v2.0"/>, but that did not work.  I tried

    <supportedRuntime version="v2.0.50727"/>, and that did not work.  I put the app.config file in the floder where the main application .exe is run from, where my dll is located and where the COTS dll is located. All no impact. 

    I would love to be able to rebuild this object, but I don't have the code.  It is from the supplier of the device we are using, and all we got was the dll file.

    Any other suggestions?

    Thanks.


    Writing software since 1969.

  • mercoledì 14 marzo 2012 17:45
     
     

    I have now also tried changing the app.config to include:

    <startup useLegacyV2RuntimeActivationPolicy="true">

    no difference.

    additional informaion, from the Output window:

    CLR:(C:\working\sw-dgx\DgxCaptureApp\Debug\P1CaptureCoreNet32.dll) ERR: Rejecting IJW module built against v2.0.50727 because it could be loaded into another runtime in this process.



    Writing software since 1969.

  • giovedì 15 marzo 2012 20:09
     
     

    Some additional information:

    I do have a project where I am able to load and access COTS dll.
    I attempted to create a new VS Project (V4 C++ /clr console) and I copied all code, file, app.config and Project properties to the new project.  The new project has the load failure.  I ran DependencyWalker on both the running .exe and the
    non running .exe and there is a difference.

    In the project's DLL list window the running project has two additional DLLs: ADVAPI32.DLL and SHLWAPI.DLL.  In the module window, these two DLLs are listed.  In the project properties, both project have the same Linker / Input / Additional Dependencies have the same Inherited values, in the same order, and advpi32.lib and shell32.lib are in the list.

    Why the difference in DependencyWalker?  Where are ADVAPI32.DLL and SHLWAPI.DLL in the properties?


    Writing software since 1969.


    • Modificato Zeft giovedì 15 marzo 2012 20:10
    •  
  • venerdì 16 marzo 2012 13:51
     
     Con risposta

    Problem Solved.

    When using the app.config file, I needed to add to the project Properties / Build Events / Post-Build Event / Command Line  -
    copy app.config "$TargetPath).config"

    I added it to both my native project and my mixed mode dll.

    Now I can load my dll and execute my mixed mode classes.

    __________________________

    Visual Studio enhancement suggestion:
    When adding a app.config to a project, ask if the user wants to add this command to the post-build event properties.


    Writing software since 1969.



    • Contrassegnato come risposta Zeft venerdì 16 marzo 2012 13:51
    • Modificato Zeft venerdì 16 marzo 2012 14:01
    • Modificato Zeft venerdì 16 marzo 2012 14:04
    •