Utilisation d'une DLL non managée dans une application ASP.NET
Le
Tugrul Ebabil
Bonjour,
nous essayons d'utiliser une assembly non managée au sein d'une application
ASP.NET mais nous n'y arrivons pas. Voici la description du problème :
Contexte logiciel :
Serveur : Windows Server 2003.
IIS 6.0
AspNet 2.0.50727
Redistribuable Visual Studio 2005 installé.
Site et assembly compilés avec Visual Studio 2005.
Framework 2.0.50727.
Enoncé du problème :
Lors de l’exécution d’un site ASP.NET, on fait appel à du code non managé
écrit en C++. Afin de réaliser ceci, un wrapper C++ managé est utilisé pour
permettre l’appel depuis une page du site. Pour pouvoir être publié avec le
site et intégré dans le wrapper, la dll non managée supporte la CLR (mais
aucune modification de code n’a été effectuée).
Le wrapper supporte la CLR oldsyntaxe. Les deux assembly sont ajoutées aux
références du site web et sont placées sous le répertoire bin du site.
Sur le PC de développement, tout se déroule correctement.
Sur le Serveur, le message suivant apparaît:
Le module spécifié est introuvable. (Exception de HRESULT :
0x8007007E)
Description : Une exception non gérée s'est produite au moment de
l'exécution de la demande Web actuelle. Contrôlez la trace de la pile pour
plus d'informations sur l'erreur et son origine dans le code.
Détails de l'exception: System.IO.FileNotFoundException: Le module spécifié
est introuvable. (Exception de HRESULT : 0x8007007E)
Erreur source:
Une exception non gérée s'est produite lors de l'exécution de la demande Web
actuelle. Les informations relatives à l'origine et l'emplacement de
l'exception peuvent être identifiées en utilisant la trace de la pile
d'exception ci-dessous.
Trace de la pile:
--
[FileNotFoundException: Le module spécifié est introuvable. (Exception de
HRESULT : 0x8007007E)]
System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase,
Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark,
Boolean throwOnFileNotFound, Boolean forIntrospection) +0
System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef,
Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean
forIntrospection) +211
System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence
assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +141
System.Reflection.Assembly.Load(String assemblyString) +25
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String
assemblyName, Boolean starDirective) +32
[ConfigurationErrorsException: Le module spécifié est introuvable.
(Exception de HRESULT : 0x8007007E)]
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String
assemblyName, Boolean starDirective) +596
System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +3596761
System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai)
+46
System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +177
System.Web.Compilation.WebDirectoryBatchCompiler..ctor(VirtualDirectory
vdir) +267
System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(VirtualDirectory vdir, Boolean ignoreErrors) +36
System.Web.Compilation.BuildManager.BatchCompileWebDirectory(VirtualDirectory
vdir, VirtualPath virtualDir, Boolean ignoreErrors) +429
System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath
virtualPath) +73
System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath
virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean
allowBuildInPrecompile) +580
System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext
context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp,
Boolean allowBuildInPrecompile) +93
System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath
virtualPath, HttpContext context, Boolean allowCrossApp, Boolean noAssert)
+111
System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath
virtualPath, Type requiredBaseType, HttpContext context, Boolean
allowCrossApp, Boolean noAssert) +54
System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context,
String requestType, VirtualPath virtualPath, String physicalPath) +31
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)
+139
System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +120
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&
completedSynchronously) +155
--
Informations sur la version : Version Microsoft .NET Framework
:2.0.50727.832; Version ASP.NET :2.0.50727.832
Les mêmes assembly appelées par une application WinForms fonctionnent en
étant sous le répertoire courant de l‘application.
Le déplacement de la dll non managée et du wrapper sous Windows\System32
résout le problème mais n’est évidemment pas une solution envisageable.
Il ne s’agit pas d’un problème de sécurité, les droits trust level sont à
Full sous web.config.
Des recherches sur Internet nous ont amené à tenter les résolutions
suivantes :
- Nommage fort de la dll C++ non managée (snk + version + langue). Ajout de
la clé dans le fichier web_mediumtrust.config et passage du trust level à
Medium dans web.config. -> aucun résultat.
- Ajout de l’assembly C++ non managée dans le GAC. -> aucun résultat.
- Nommage fort de la dll C++ non managée et du wrapper (snk + version +
langue). Ajout de la clé dans le fichier web_mediumtrust.config et passage du
trust level à Medium dans web.config. -> aucun résultat.
- Ajout de la dll C++ non managée et du wrapper dans le GAC. -> aucun
résultat.
Est-ce que quelqu'un aurait une solution à ce problème ? Merci d'avance pour
votre aide.
Tugrul Ebabil
nous essayons d'utiliser une assembly non managée au sein d'une application
ASP.NET mais nous n'y arrivons pas. Voici la description du problème :
Contexte logiciel :
Serveur : Windows Server 2003.
IIS 6.0
AspNet 2.0.50727
Redistribuable Visual Studio 2005 installé.
Site et assembly compilés avec Visual Studio 2005.
Framework 2.0.50727.
Enoncé du problème :
Lors de l’exécution d’un site ASP.NET, on fait appel à du code non managé
écrit en C++. Afin de réaliser ceci, un wrapper C++ managé est utilisé pour
permettre l’appel depuis une page du site. Pour pouvoir être publié avec le
site et intégré dans le wrapper, la dll non managée supporte la CLR (mais
aucune modification de code n’a été effectuée).
Le wrapper supporte la CLR oldsyntaxe. Les deux assembly sont ajoutées aux
références du site web et sont placées sous le répertoire bin du site.
Sur le PC de développement, tout se déroule correctement.
Sur le Serveur, le message suivant apparaît:
Le module spécifié est introuvable. (Exception de HRESULT :
0x8007007E)
Description : Une exception non gérée s'est produite au moment de
l'exécution de la demande Web actuelle. Contrôlez la trace de la pile pour
plus d'informations sur l'erreur et son origine dans le code.
Détails de l'exception: System.IO.FileNotFoundException: Le module spécifié
est introuvable. (Exception de HRESULT : 0x8007007E)
Erreur source:
Une exception non gérée s'est produite lors de l'exécution de la demande Web
actuelle. Les informations relatives à l'origine et l'emplacement de
l'exception peuvent être identifiées en utilisant la trace de la pile
d'exception ci-dessous.
Trace de la pile:
--
[FileNotFoundException: Le module spécifié est introuvable. (Exception de
HRESULT : 0x8007007E)]
System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase,
Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark,
Boolean throwOnFileNotFound, Boolean forIntrospection) +0
System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef,
Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean
forIntrospection) +211
System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence
assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +141
System.Reflection.Assembly.Load(String assemblyString) +25
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String
assemblyName, Boolean starDirective) +32
[ConfigurationErrorsException: Le module spécifié est introuvable.
(Exception de HRESULT : 0x8007007E)]
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String
assemblyName, Boolean starDirective) +596
System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +3596761
System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai)
+46
System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +177
System.Web.Compilation.WebDirectoryBatchCompiler..ctor(VirtualDirectory
vdir) +267
System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(VirtualDirectory vdir, Boolean ignoreErrors) +36
System.Web.Compilation.BuildManager.BatchCompileWebDirectory(VirtualDirectory
vdir, VirtualPath virtualDir, Boolean ignoreErrors) +429
System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath
virtualPath) +73
System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath
virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean
allowBuildInPrecompile) +580
System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext
context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp,
Boolean allowBuildInPrecompile) +93
System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath
virtualPath, HttpContext context, Boolean allowCrossApp, Boolean noAssert)
+111
System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath
virtualPath, Type requiredBaseType, HttpContext context, Boolean
allowCrossApp, Boolean noAssert) +54
System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context,
String requestType, VirtualPath virtualPath, String physicalPath) +31
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)
+139
System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +120
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&
completedSynchronously) +155
--
Informations sur la version : Version Microsoft .NET Framework
:2.0.50727.832; Version ASP.NET :2.0.50727.832
Les mêmes assembly appelées par une application WinForms fonctionnent en
étant sous le répertoire courant de l‘application.
Le déplacement de la dll non managée et du wrapper sous Windows\System32
résout le problème mais n’est évidemment pas une solution envisageable.
Il ne s’agit pas d’un problème de sécurité, les droits trust level sont à
Full sous web.config.
Des recherches sur Internet nous ont amené à tenter les résolutions
suivantes :
- Nommage fort de la dll C++ non managée (snk + version + langue). Ajout de
la clé dans le fichier web_mediumtrust.config et passage du trust level à
Medium dans web.config. -> aucun résultat.
- Ajout de l’assembly C++ non managée dans le GAC. -> aucun résultat.
- Nommage fort de la dll C++ non managée et du wrapper (snk + version +
langue). Ajout de la clé dans le fichier web_mediumtrust.config et passage du
trust level à Medium dans web.config. -> aucun résultat.
- Ajout de la dll C++ non managée et du wrapper dans le GAC. -> aucun
résultat.
Est-ce que quelqu'un aurait une solution à ce problème ? Merci d'avance pour
votre aide.
Tugrul Ebabil

Poser une question


Bonjour,
Etes-vous sûr que toutes les DLL que votre application ai besoin se trouvent
dans le répertoire bin de votre site ?
Cordialement
--
Gilles TOURREAU - MVP C#
S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
toutes les DLL managées, les wrappers et les DLL non managées nécessaires à
l'application ASP.NET se trouvent dans le répertoire bin du site.
Comme je l'ai écrit, en déplaçant les wrappers et les DLL non managées dans
le répertoire System32 de Windows, ça marche.
Pour être sûr qu'il ne s'agissait pas d'un problème de dépendance manquante,
nous avons copié le contenu du répertoire System32 de Windows dans le
répertoire bin du site. Ceci n'a donné aucun résultat.
Il semblerait donc que les DLL non managées ne soient recherchées que dans
le répertoire System32.
Vu ce comportement, je me pose la question suivante : peut-on utiliser des
DLLs non managées dans une application ASP.NET ?
Cordialement,
Tugrul Ebabil
"Gilles TOURREAU [MVP]" a écrit :
http://msdn2.microsoft.com/en-us/library/7d83bc18(VS.80).aspx (par exemple
essayer en modifiant la variable d'environnement ? ou en modifiant le
wrapper pour qu'il charge explicitement la DLL ?)
Egalement la notion de dossier courant pour une application ASP.NET n'a pas
vraiment lieu d'être (je crois que c'est également le dossier system32).
--
Patrice
je ne l'avais pas écrit mais nous avons également essayé d'ajouter le
répertoire bin du site dans la variable d'environnement PATH, ça n'a pas
marché non plus.
Nous avons aussi essayé de charger dynamiquement les DLL non managées dans
les wrapper en utilisant les chemins complets, ça n'a pas marché non plus.
Si j'ai bien compris le fonctionnement des applications ASP.NET, les DLL qui
sont dans le répertoire bin du site sont recopiées dans un répertoire
temporaire (documents and settings...). L'exécution se fait dans ce
répertoire temporaire.
On voit bien que lors de la copie, les DLL non managées ne sont pas
recopiées dans le répertoire temporaire. Ce qui ne se trouve pas dans ce
répertoire est cherché dans System32. Il semblerait que la variable
d'environnement PATH ne soit absolument pas utilisée. Si nous copions les DLL
non managées dans le répertoire temporaire, ça marche.
Cordialement,
Tugrul Ebabil
"Patrice" a écrit :
Je vais essayé de répondre : oui on peut utiliser des DLL non managées
en ASP.NET, quelque soit leurs localisations sur le poste.
J'avais du pour un prjet utiliser des DLL C++/Win32 dont leurs
localisations étaient définies dans la Registry (et autre qu'un
répertoire system).
De mémoire j'avais utilisé un mécanisme pour construire dynamiquement
une assembly .NET qui chargeait la DLL Win32 en passant le Path...
Si c'est important je peux chercher les sources si je les ai encore,
mais c'était vraiment usine à gaz... et c'était ma 1° tâche en .NET,
quand j'ai découvert cet environement... :
--
Delf