72 votes

Les DLL non gérées ne se chargent pas sur le serveur ASP.NET

Cette question concerne un site Web ASP.NET, initialement développé en VS 2005 et maintenant en VS 2008.

Ce site Web utilise deux DLL externes non gérées qui ne sont pas .NET. Je ne dispose pas du code source pour les compiler et je dois les utiliser telles quelles.

Ce site web fonctionne bien à partir de Visual Studio, en localisant et en accédant correctement à ces DLL externes. Cependant, lorsque le site Web est publié sur un serveur Web (exécutant IIS6 et ASP.NET 2.0) plutôt que sur le PC de développement, il ne peut pas localiser et accéder à ces DLL externes, et j'obtiens l'erreur suivante :

Unable to load DLL 'XYZ.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Les DLL externes sont situées dans le répertoire bin du site Web, avec les DLL gérées qui les enveloppent et toutes les autres DLL du site Web.

Une recherche sur ce problème révèle que de nombreuses autres personnes semblent avoir le même problème d'accès aux DLL externes non.NET à partir de sites Web ASP.NET, mais je n'ai pas trouvé de solution qui fonctionne.

J'ai essayé ce qui suit :

  • Exécuter DEPENDS pour vérifier les dépendances afin d'établir que les trois premières sont dans le répertoire System32 dans le chemin, le dernier est dans le cadre .NET 2 Framework.
  • J'ai mis les deux DLL et leurs dépendances dans System32 et redémarré le serveur, mais le site web ne pouvait toujours pas ne pouvait pas charger ces DLLs externes.
  • J'ai donné les droits complets à ASPNET, IIS_WPG et IUSR (pour ce serveur) sur le répertoire bin du site web et j'ai reboosté le site. le répertoire bin du site web et redémarré, mais le site web ne pouvait toujours pas charger ces DLL externes.
  • J'ai ajouté les DLL externes en tant qu'éléments existants aux projets et j'ai configuré leur propriété "Copy to Output" à "Copy Always", et le site web ne trouve toujours pas les DLLs.
  • J'ai également défini leur propriété "Build Action" sur "Embedded resource". le site Web ne trouve toujours pas les DLL.

Toute aide pour résoudre ce problème serait grandement appréciée !

4voto

yzorg Points 1139

Une autre option consiste à intégrer la DLL native comme ressource dans la DLL gérée. C'est plus compliqué en ASP.NET, car il faut écrire dans un dossier temporaire au moment de l'exécution. Cette technique est expliquée dans une autre réponse de SO .

2voto

annakata Points 42676

Toujours utile vérifier le chemin dans vos paramètres d'environnement également.

2voto

Ram Chavakula Points 11

J'ai rencontré le même problème. Et j'ai essayé toutes les options ci-dessus, copier vers system32, inetpub, définir l'environnement du chemin, etc rien n'a fonctionné. Ce problème est finalement résolu en copiant la dll non gérée dans le répertoire bin de l'application web ou du service web.

2voto

Mad Dog Points 28

Аaprès avoir lutté toute la journée sur ce problème et enfin j'ai trouvé une solution qui me convient. C'est juste un test, mais la méthode fonctionne.

namespace TestDetNet
{
    static class NativeMethods
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);
    }

    public partial class _Default : System.Web.UI.Page
    {
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate int GetRandom();

        protected System.Web.UI.WebControls.Label Label1;
        protected void Page_Load(object sender, EventArgs e)
        {
            Label1.Text = "Hell'ou";
            Label1.Font.Italic = true;
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            if (File.Exists(System.Web.HttpContext.Current.Server.MapPath("html/bin")+"\\DelphiLibrary.dll")) {
                IntPtr pDll = NativeMethods.LoadLibrary(System.Web.HttpContext.Current.Server.MapPath("html/bin")+"\\DelphiLibrary.dll");
                if (pDll == IntPtr.Zero) { Label1.Text =  "pDll is zero"; }
                else
                {
                  IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "GetRandom");
                  if (pAddressOfFunctionToCall == IntPtr.Zero) { Label1.Text += "IntPtr is zero";   }
                  else
                  {
                    GetRandom _getRandom = (GetRandom)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall,typeof(GetRandom));

                    int theResult = _getRandom();

                    bool result = NativeMethods.FreeLibrary(pDll);
                    Label1.Text = theResult.ToString();
                  }
                }
          }
        }
    }
}

1voto

jlew Points 5666

Exécutez DEPENDS sur XYZ.dll directement, dans l'emplacement où vous l'avez déployé. Si cela ne révèle rien de manquant, utilisez l'outil fuslogvw du SDK de la plate-forme pour repérer les erreurs de chargement. En outre, les journaux d'événements contiennent parfois des informations sur les échecs de chargement des DLL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X