I’m trying to build a VS 2005 website project which depends on several managed C++ assemblies. One of the managed C++ assemblies depends (static-load) on an unmanaged DLL which uses __declspec(dllexport) to export classes.
For some reason, I get the following build error:
Error 4 The specified module could not be found. (Exception from HRESULT: 0x8007007E)
(From build output details):
(0): Build (web): The specified module could not be found. (Exception from HRESULT: 0x8007007E)
when I build with the unmanaged DLL in the website’s \Bin\ directory, but not in the path. If I put the unmanaged DLL in the path, then re-start visual studio, it builds and runs just fine.
Note: This thread seemed related, but I haven’t gotten as far as deployment yet: Unmanaged DLLs fail to load on ASP.NET server
Is there any way to get this .sln building correctly with unmanaged DLL’s in \Bin\ rather than the path? (I’d really prefer to keep these as part of the website, not the system)
Edit:
It seems I’ve misunderstood the purpose of the \Bin\ folder to some degree. Sounds like nothing except managed assemblies should go there. (So COM objects and other unmanaged DLLs they rely on which I’ve been placing there probably belong someplace else.)
I believe that ASP.NET copies your assemblies around quite a bit, to avoid locking the original DLL (which would prevent overwriting with a newer version). Then when you do overwrite it, it needs a copy of the old version until all outstanding requests complete, alongside the new version being used for new requests.
In summary, your DLL doesn’t run from the
\bin\directory where you put it, and it looks for native dependencies where it actually does run.Your options are to put the native DLLs in the path, or else add code to explicitly copy them to the “real” assembly directory as needed. But your code shouldn’t even have permission to write to the filesystem, so I think you’re stuck using the path.
Do note, though, that you can add directories to the application’s own environment, without affecting the global path. For example, p/invoke
SetDllDirectoryDon’t add\bin\though. Put your native DLLs in a separate directory like\bin\nativeor\bin\x86, so when you change the search path you don’t change which managed DLLs are found.Edit:
This only works if the managed DLL delay loads any unmanaged native DLLs it links against (using /DELAYLOAD). Otherwise compilation of global.asax (or wherever the path setting happens) will fail.