2012-02-09 3 views
9

Devo includere un componente C++/CLI (gestito) in uno dei miei progetti ASP.NET, che fa riferimento a se stesso un altro (non gestito) DLL C++. Non dovrebbe esserci alcun problema - .NET 3.5 è felice quando si compila il progetto, tutto sembra a posto. Il componente C++/CLI e le altre DLL C++ sono compilati da un altro reparto come Versione di rilascio con "Qualsiasi CPU" in Visual Studio 2005. VC++ 2005 Redistributable package è installato. E lo stesso codice funziona senza problemi quando lo eseguo all'interno di una normale applicazione di console .NET."Impossibile trovare il modulo" errore con componente C++/CLI in ASP.NET

Ora, mentre questo codice funziona in un'app console, non viene ospitato correttamente da ASP.NET - genera un errore sul caricamento iniziale della pagina (anche prima di entrare in Global.asax). per il test e il debug, ho usato due configurazioni di macchine:

  1. locale Dev PC: Windows XP, 32 bit, VC++ 2005 Redist della confezione, Visual Studio 2010, ASP.NET 3.5, Compilazione "Qualsiasi CPU" , Hosting in Server Web Development (Cassini)
  2. test Server (computer di destinazione): Windows 7, 64 bit, VC++ 2005 Redist pacchetto, hosting in IIS 7, AppPool ha "Attiva applicazioni a 32 bit" set

Su entrambe le macchine nello stesso seguente errore si verifica quando inizio l'applicazione ASP.NET:

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 

Ora questo è strano ... Non dice nulla su ciò che assemblaggio manca, anche Fuslogvw.exe o sxstrace.exe non stanno registrando nulla. Inoltre di coures sembra che l'errore dipenda dall'assembly C++/CLI o dalle DLL C++ non gestite. Se rimuovo il riferimento all'assembly C++/CLI dal mio progetto ASP.NET e il codice, funziona correttamente. Ora, poiché l'assembly C++/CLI dipende da DLL C++ nativi a cui non si fa riferimento nel progetto ASP.NET, ho copiato tutte le DLL C++ dipendenti nella cartella "bin" della cartella di output del progetto ASP.NET (come per la console workgin applicazione). Mentre tutte le cose C++ sono state compilate in modalità Release, con il pacchetto di ridistribuzione VC++ corretto installato, dovrebbero essere presenti tutte le dipendenze. Naturalmente so che c'è un FileNotFoundException, ma non riesco a capire cosa manca ...

Come detto: lo stesso codice per accedere al componente C++/CLI funziona in un'applicazione di console .NET 3.5 su entrambi i PC di test (dove Dispongo delle stesse dipendenze distribuite) con le stesse DLL C++ dipendenti distribuite nella cartella di output, solo in ASP.NET ottengo l'errore sopra riportato.

Qualche suggerimento su come posso eliminare il problema o come posso rintracciarlo ulteriormente?

(Naturalmente ho cercato StackOverflow e Google per il problema, ad esempio, ho trovato questi collegamenti, ma non ha aiutato:
-"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)

risposta

4

Il tuo codice raggiunge lo _nLoad e questo è buono perché hanno passato tutti i controlli per il caricamento e passare al core per caricare effettivamente la DLL, e lì fallisce.

Per avviare il download del Dependency Walker da http://www.dependencywalker.com/ e usarlo su dll per scoprire quali altre risorse questa dll ha bisogno per funzionare. Sospetto che non possa caricare altri file dll.

Ulteriori forse questa dll cerca altri file che non riescono a trovare e questo è il motivo per cui non è possibile caricare. Il secondo modo è utilizzare lo File Monitor o lo Process Monitor da sysinternals per trovare ciò che non riesce a caricare.

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

+0

Grazie all'inizio. Ho usato Dependency Walker prima senza trovare problemi. Mi chiedo semplicemente perché funziona l'applicazione console .NET con gli stessi assembly distribuiti, mentre l'applicazione ASP.NET ha esito negativo? È strano ... – Matthias

+0

@Matthias mentre scrivo, probabilmente perché non riesco a caricare alcuni file di risorse. Usa anche il monitor di file per trovarli. – Aristos

+0

Ok, con ProcMon (primo utente) ho fatto un passo in più (grazie!), Ma spero che tu possa spiegare i risultati: ho visto che il processo 'WebDev.WebServer20.exe' vuole accedere al ** nativo C++ DLL ** e le DLL core VC++ (msvcr80.dll, mfc80.dll, msvcm80.dll, ...) ** non nella cartella di distribuzione, ma nelle cartelle della variabile di ambiente 'PATH'. Ora è possibile convincere l'applicazione ASP.NET delle DLL nella sua cartella di distribuzione, nonché i file core VC++ distribuiti in 'C: \ Windows \ winsxs'? La distribuzione dovrebbe essere così semplice ... – Matthias

5

ProcMon mi ha salvato.

Anche il percorso era il mio problema. Sembra che IIS stia creando una copia shadow di ogni dll gestita nella cartella C: \ Windows \ System32 \ inetsrv. Ma questo non è il caso per il codice non gestito. Quando deve caricare una DLL non gestita, cerca nel percorso ambientale e non nella directory bin dell'applicazione in IIS.

Mille grazie Aristos !!

+0

Ma come hai risolto questo problema? Aggiunta cartella bin a PATH? – CrazyMORF