Question

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

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

Ce site Web fonctionne correctement à partir de Visual Studio. Il permet de localiser et d'accéder correctement à ces DLL externes. Toutefois, 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 ni accéder à ces DLL externes et le message d'erreur suivant s'affiche:

Impossible de charger la DLL 'XYZ.dll': le module spécifié est introuvable. (Exception de HRESULT: 0x8007007E)

Les DLL externes se trouvent dans le répertoire bin du site Web, avec les DLL gérées qui les encapsulent et toutes les autres DLL du site Web.

La recherche de ce problème révèle que de nombreuses personnes semblent avoir le même problème pour accéder aux DLL non.NET externes à partir de sites Web ASP.NET, mais je n’ai pas trouvé de solution qui fonctionne.

J'ai essayé les solutions suivantes:

  • Lancer DEPENDS pour vérifier les dépendances afin d’établir que les trois premiers sont dans le répertoire System32 dans le chemin, le dernier est dans le .NET 2 cadre.
  • Je mets les deux DLL et leurs dépendances dans System32 et redémarré le serveur, mais le site Web toujours Impossible de charger ces DLL externes.
  • Attribuez tous les droits sur ASPNET, IIS_WPG et IUSR (pour ce serveur) à le répertoire bin du site Web et redémarré, mais le site Web ne pouvait toujours pas charger ces DLL externes.
  • Ajout des DLL externes en tant qu'éléments existants aux projets et définition leur "Copier vers la sortie" propriété à "Copier toujours" et site Web n'arrive toujours pas à trouver les DLL.
  • Définissez également leur " action de construction " propriété de " ressource incorporée " et Le site Web ne parvient toujours pas à trouver les DLL.

Toute aide concernant ce problème serait grandement appréciée!

Était-ce utile?

La solution

Essayez de placer les dll dans le répertoire \ System32 \ Inetsrv. C’est le répertoire de travail pour IIS sur Windows Server.

Si cela ne fonctionne pas, essayez de placer les dll dans le répertoire System32 et les fichiers de dépendance dans le répertoire Inetsrv.

Autres conseils

Cela se produit parce que les dll gérées sont copiées dans un cliché instantané dans un emplacement temporaire du répertoire .NET Framework. Voir http://msdn.microsoft.com/en-us/library/ms366723. aspx pour plus de détails.

Malheureusement, les dll non gérées ne sont PAS copiées et le processus ASP.NET ne sera pas en mesure de les trouver lorsqu'il devra les charger.

Une solution simple consiste à placer les dlls non gérées dans un répertoire qui se trouve dans le chemin du système (tapez "chemin" sur la ligne de commande pour afficher le chemin sur votre ordinateur) afin qu'elles puissent être trouvées par ASP.NET. processus. Le répertoire System32 est toujours dans le chemin. Vous pouvez donc y placer les dll non gérées, mais je vous recommande d’ajouter un autre dossier au chemin, puis d’y ajouter les dll pour éviter de polluer le répertoire System32. Un gros inconvénient de cette méthode est que vous devez renommer les dlls non gérées pour chaque version de votre application et que vous pouvez rapidement disposer de votre propre enfer de dll.

Au lieu de placer la dll dans un dossier déjà présent dans le chemin (comme system32), vous pouvez modifier la valeur du chemin dans votre processus à l'aide du code suivant

System.Environment.SetEnvironmentVariable("Path", searchPath + ";" + oldPath)

Ensuite, lorsque LoadLibrary essaiera de trouver la DLL non gérée, il analysera également searchPath. Cela peut être préférable à un désordre dans System32 ou d’autres dossiers.

En ajoutant à la réponse de Matt, voici ce qui a finalement fonctionné pour moi sur un serveur 64 bits 2003 / IIS 6:

  1. assurez-vous que vos dlls / asp.net ont la même version (32/64 bits)
  2. Placez les dlls non gérées dans le répertoire inetsrv (notez que dans les fenêtres 64 bits, cela se trouve sous syswow64, même si le répertoire sys32 / inetsrv est créé)
  3. Laissez les dll gérées dans / bin
  4. Assurez-vous que les deux ensembles de dll disposent des autorisations de lecture / exécution

Consultez FileMon ou ProcMon et filtrer les noms des DLL problématiques. Cela vous indiquera quels répertoires sont analysés à la recherche des DLL et tous les problèmes d’autorisation éventuels.

Une autre option consiste à incorporer la DLL native en tant que ressource dans la DLL gérée. C’est plus compliqué dans ASP.NET, car cela nécessite l’écriture dans un dossier temporaire au moment de l’exécution. Cette technique est expliquée dans une autre réponse à une offre à commandes .

Cela vaut toujours la peine de cochez la case chemin variable également dans les paramètres de votre environnement.

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

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

& # 1040; a lutté toute la journée pour résoudre ce problème et j'ai finalement trouvé une solution qui me convient. Ce n'est qu'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();
                  }
                }
          }
        }
    }
}

Sur Application_start, utilisez ceci: (personnalisez les dossiers / bin / x64 et bin / dll / x64 selon vos besoins)

String _path = String.Concat(System.Environment.GetEnvironmentVariable("PATH")
                ,";"
                , System.Web.Hosting.HostingEnvironment.MapPath("~/bin/x64")
                ,";"
                , System.Web.Hosting.HostingEnvironment.MapPath("~/bin/dll/x64")
                ,";"
                );
            System.Environment.SetEnvironmentVariable("PATH", _path, EnvironmentVariableTarget.Process);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top