none
WebService et dll RRS feed

  • 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 ?
    vendredi 3 avril 2009 08:57

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#
    jeudi 7 mai 2009 06:59
    Modérateur
  • 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#
    dimanche 26 juillet 2009 12:59
    Modérateur

Toutes les réponses

  • Bonjour,

    Etes-vous sur que les dépendances des DLL de MainDLL.dll sont bien présentes ?

    Cordialement
    Gilles TOURREAU - MVP C#
    jeudi 23 avril 2009 20:31
    Modérateur
  • 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,
    lundi 27 avril 2009 08:35
  • Bonjour,

    Est-ce que votre serveur est en 64-bit ? Et votre poste en 32-bit ?

    Cordialement
    Gilles TOURREAU - MVP C#
    lundi 4 mai 2009 18:32
    Modérateur
  • Bonjour,

    En effet, mon poste est un Vista 32-bit et le serveur est en 64.
    Mais j'ai eu le même problème en testant le webservice sur une autre machine sous Vista en 32-bit et la version Démo de windows Server 32-bit...

    Cordialement
    mardi 5 mai 2009 07:47
  • 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#
    jeudi 7 mai 2009 06:59
    Modérateur
  • 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,
    mercredi 13 mai 2009 12:41
  • 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#
    samedi 20 juin 2009 18:48
    Modérateur
  • 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
    lundi 22 juin 2009 08:29
  • 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#
    dimanche 26 juillet 2009 12:59
    Modérateur