Meilleur auteur de réponses
WebService et dll

Question
-
Bonjour,
J'ai créé un site web comportant un webService, en utilisant Visual Web Developper 2008 (Express Edition) sous Vista. Le service web utilise une dll (MainDLL) qui a besoin de connaître son environnement, car elle appelle elle-même d'autres dlls, des dictionnaires etc. Dans mon fichier Web.config, j'ai donc un paramètre qui indique le chemin absolu de MainDll. Cette Dll a été écrite en Visual Prolog 7.2.
En Local, tout marche bien, le webservice utilise la dll et la vie est belle.
Par contre, si j'installe le projet Visual Web Developper sur une autre machine (un autre Vista, ou windows server 2008), en adaptant l'adresse du fichier service.asmx et le chemin de MainDll, le web service n'arrive pas à entrer en contact avec la dll : il me retourne
"Unable to load DLL 'MainDll.dll': Attempt to access invalid address. (Exception from HRESULT: 0x800701E7)",
mais dans le journal que je lui fais écrire à sa tentative d'accès à la dll, l'adresse est la bonne : la dll est bien là.
J'ai pensé à un problème d'autorisations, j'ai fourni le contrôle total à Network Service (indiqué par le pool d'applications) au répertoire de ma dll, mais ça n'a rien changé. Ensuite j'ai attribué le contrôle total à EveryOne, mais aucun changement...
Je tourne en rond. Quelqu'un a-t-il une idée ?
Réponses
-
Bonjour,
Ce que je peux vous dire c'est que l'erreur que vous obtenez ne provient pas d'un problème de droit au niveau de l'accès à la DLL, mais un problème d'accès à une fonction de la DLL.
Le plus souvent ces erreurs sont dûe à des problèmes de conventions d'appel des fonctions.
Pouvez-vous nous montrer comment vous appellez et utilisez votre DLL sur votre site ASP .NET ?
Cordialement
Gilles TOURREAU - MVP C#- Marqué comme réponse Gilles TOURREAUModerator dimanche 26 juillet 2009 12:59
-
Le problème a été réglé au niveau de l'attribut DllImport en spécifiant les conventions d'appels :
[DllImport(@"TestA.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "test")]
Gilles TOURREAU - MVP C#- Marqué comme réponse Gilles TOURREAUModerator dimanche 26 juillet 2009 12:59
Toutes les réponses
-
-
Bonjour, et merci pour votre réponse.
Oui, les dépendances sont présentes, et j'ai les même fichiers sur ma propre machine que sur mon serveur... sauf que chez moi tout fonctionne. C'est assez déprimant.
Du coup, j'ai développé un projet de test plus léger, avec une seule dll Prolog qui n'utilise aucune ressource externe (mis à part des dlls sytèmes qui sont présentes). Le comportement est le même : chez moi le test en passant par service.asmx est concluant (en attribuant le contrôle total à "Tout le monde" pour le répertoire où est stockée ma dll). Mais si je déplace tout sur mon serveur, en règlant de la même façon le contrôle total sur le répertoire de ma dll: je me retrouve toujours avec :
"Unable to load DLL 'TestA.dll': Attempt to access invalid address. (Exception from HRESULT: 0x800701E7)"
Auriez-vous une idée ?
Bien cordialement, -
-
-
Bonjour,
Ce que je peux vous dire c'est que l'erreur que vous obtenez ne provient pas d'un problème de droit au niveau de l'accès à la DLL, mais un problème d'accès à une fonction de la DLL.
Le plus souvent ces erreurs sont dûe à des problèmes de conventions d'appel des fonctions.
Pouvez-vous nous montrer comment vous appellez et utilisez votre DLL sur votre site ASP .NET ?
Cordialement
Gilles TOURREAU - MVP C#- Marqué comme réponse Gilles TOURREAUModerator dimanche 26 juillet 2009 12:59
-
Bonjour,
Mais si c'est un problème de code, cela devrait être du "tout ou rien", non ?
Un même code pourrait fonctionner sur mon ordinateur mais pas sur un autre ?
En tout cas merci de vous intéresser à mon problème !
Voici la classe qui charge et fournit la méthode de ma dll :
public class DllImporter { public DllImporter() { } [DllImport("kernel32.dll", CharSet = CharSet.Auto)] static extern IntPtr LoadLibrary(String lpFileName); [DllImport(@"TestA.dll", EntryPoint = "init")] static extern IntPtr _init(IntPtr pathDLL); [DllImport(@"TestA.dll", EntryPoint = "test")] static extern IntPtr _test(IntPtr pathDLL, IntPtr Input); public static String LoadThisLibrary(String dllPath) { String strReturnedData = String.Empty; try { strReturnedData = Marshal.PtrToStringAuto(LoadLibrary(dllPath)); } catch (Exception ee) { strReturnedData = ee.Message; } return strReturnedData; } public static String SetInit(String dllPath) { String strReturnedData = String.Empty; try { IntPtr iprPath = new IntPtr(); iprPath = Marshal.StringToHGlobalAuto(dllPath); strReturnedData = Marshal.PtrToStringAuto(_init(iprPath)); } catch (Exception ee) { strReturnedData = ee.Message; } return strReturnedData; } public static String test(String IDclient, String InputClient) { String strReturnedData = String.Empty; try { IntPtr Id = new IntPtr(); Id = Marshal.StringToHGlobalAuto(IDclient); IntPtr Input = new IntPtr(); Input = Marshal.StringToHGlobalAuto(InputClient); strReturnedData = Marshal.PtrToStringAuto(_test(Id, Input)); } catch (Exception ee) { strReturnedData = ee.Message; } return strReturnedData; } }
La Dll requiert une initialisation, qui est effectuée au lancement de l'application, ce qui donne au niveau du global.asax :
<script runat="server"> protected void Application_Start(Object sender, EventArgs e) { String strPathDLL = System.Configuration.ConfigurationManager.AppSettings["PathDLL"].ToString(); if (!System.IO.Directory.Exists(strPathDLL)) { Application["SiteInError"] = String.Format(@"!System.IO.Directory.Exists(""{0}"")", strPathDLL); return; } Environment.CurrentDirectory = strPathDLL; DllImporter.LoadThisLibrary(strPathDLL); String ValInit = DllImporter.SetInit(strPathDLL); if (ValInit == "OK") { Application["SiteInError"] = String.Format(@"DllImporter.SetInit(""{0}"")", strPathDLL); return; } return; }
La webmethod déclarée dans service.cs qui utilise la dll est la suivante :
[WebMethod] public String test(String ID, String Input) { return DllImporter.test(ID, Input); }
Les appels à la méthode test se font uniquement en local, en passant pas la page service.asmx.
C'est à peu près tout. Je peux vous envoyer le site complet si vous voulez.
Cordialement, -
Bonjour,
Avez-vous résolu votre problème ? Si oui, pouvez-vous m'envoyer un bout projet sur gilles.tourreau@pos.fr qui reproduirait le problème ?
Cordialement
Gilles TOURREAU - MVP C# -
Bonjour ,
Non, je n'ai toujours pas de solution (et commence à désespérer quelque peu). Je vous envoie tout de même le projet (objet du message : WebService et dll - projet récalcitrant)...
Sinon, plutôt qu'un problème dans le code, je pense à un paramètre de configuration de IIS qui différerait entre ma machine et les autres que j'ai testées, mais lequel...?
Cordialement -
Le problème a été réglé au niveau de l'attribut DllImport en spécifiant les conventions d'appels :
[DllImport(@"TestA.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "test")]
Gilles TOURREAU - MVP C#- Marqué comme réponse Gilles TOURREAUModerator dimanche 26 juillet 2009 12:59