Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"module could not be found" error with C++/CLI component in ASP.NET

I have to include a (managed) C++/CLI component in one of my ASP.NET projects, that references for itself some other (unmanaged) C++ DLLs. Should be no problem - .NET 3.5 is happy when compiling the project, everything seems fine. The C++/CLI component and the other C++ DLLs are compiled by another department as Release version with "Any CPU" in Visual Studio 2005. The VC++ 2005 Redistributable package is installed. And the same code works without problem when I run it inside of a normal .NET console application.

Now while this code works in a console app, it's not being hosted correctly by ASP.NET - it leads an error on the initial page load (even before stepping into the Global.asax). For testing and debugging, I have used two machine configurations:

  1. Local Dev PC: Windows XP, 32 Bit, VC++ 2005 Redist Package, Visual Studio 2010, ASP.NET 3.5, Compiling "Any CPU", Hosting in Web Development Server (Cassini)
  2. Test Server (target machine): Windows 7, 64 Bit, VC++ 2005 Redist Package, Hosting in IIS 7, AppPool has "Enable 32-Bit Applications" set

On both machines the same following error occurs when I start the ASP.NET application:

Exception Details: System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:
[FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)]
 System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) +0
 System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) +43
 System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +127
 System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +142
 System.Reflection.Assembly.Load(String assemblyString) +28
 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +46

[ConfigurationErrorsException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)]
 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +613
 System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +203
 System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +105
 System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +178
 System.Web.Compilation.WebDirectoryBatchCompiler..ctor(VirtualDirectory vdir) +163
 System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(VirtualDirectory vdir, Boolean ignoreErrors) +53
 System.Web.Compilation.BuildManager.BatchCompileWebDirectory(VirtualDirectory vdir, VirtualPath virtualDir, Boolean ignoreErrors) +175
 System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) +86
 System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) +261
 System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) +101
 System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean noAssert) +126
 System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp, Boolean noAssert) +62
 System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath) +33
 System.Web.UI.PageHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath) +40
 System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig) +160
 System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +93
 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Now this is weird... It doesn't say anything about what assembly is missing, even Fuslogvw.exe or sxstrace.exe aren't logging anything. Moreover of coures it seems that the error depends on the C++/CLI assembly or on the unmanaged C++ DLLs. If I remove the C++/CLI assembly reference from my ASP.NET project and the code, it works fine. Now because the C++/CLI assembly depends on native C++ DLLs that are not referenced in the ASP.NET project, I copied all dependent C++ DLLs to the "bin" folder of the ASP.NET project's output folder (same as for the workgin console application). While every C++ stuff has been compiled in Release mode, with the correct VC++ Redist Package installed, there should be all dependencies in place. Of course I know there is a FileNotFoundException, but I cannot work out what's missing...

As said: the same code for accessing the C++/CLI component works in a .NET 3.5 console application on both test PCs (where I have the same dependencies deployed) with the same dependent C++ DLLs deployed into the output folder, just in ASP.NET I get the above error.

Any suggestions how I can get rid of the problem or how I can track it further?

(Of course I searched StackOverflow and Google for the problem, e.g. I found these links, but they didn't help:
- "The specified module could not be found" error when running C# ASP.NET web service referring C++ dll
- Access x86 COM from x64 .NET
- ASP.NET application developed in 32 bit environment not working in 64 bit environment
- Module Not Found Exception From .NET 2.0 Web Service On Windows Server 2008 R2 )

like image 271
Matthias Avatar asked Feb 09 '12 09:02

Matthias


2 Answers

ProcMon saved me.

The path was my problem too. It seems that IIS is creating a shadow copy of each managed dll in C:\Windows\System32\inetsrv folder. But this in not the case for unmanaged code. When it has to load an unmanaged dll, it search the environmental path and not the bin directory of the application in IIS.

Many thanks Aristos!!

like image 54
ThomasV Avatar answered Oct 06 '22 03:10

ThomasV


Your code reach the _nLoad and this is good because have pass all checks for loading and move to the core to actually load the dll, and there its fail.

For start download the Dependency Walker from http://www.dependencywalker.com/ and use it on dll to find out what other resource this dll needs to run. I suspect that can not load some other dll files.

Additional maybe this dll search for other files that can not find and thats why can not load. The second way is to use the File Monitor, or the Process Monitor from sysinternals to find what fail to load.

http://technet.microsoft.com/en-us/sysinternals
http://technet.microsoft.com/en-us/sysinternals/bb896645

like image 29
Aristos Avatar answered Oct 06 '22 04:10

Aristos