Неуправляемые библиотеки DLL не удалось загрузить на сервер ASP.NET

StackOverflow https://stackoverflow.com/questions/344608

  •  19-08-2019
  •  | 
  •  

Вопрос

Этот вопрос относится к ASP.NET веб-сайту, первоначально разработанному в VS 2005, а теперь в VS 2008.

Этот веб-сайт использует две неуправляемые внешние библиотеки DLL, которые таковыми не являются .У NET и меня нет исходного кода для их компиляции, и мы вынуждены использовать их как есть.

Этот веб-сайт отлично работает из Visual Studio, правильно размещая эти внешние библиотеки DLL и получая к ним доступ.Однако, когда веб-сайт публикуется на веб-сервере (под управлением IIS6 и ASP.NET 2.0), а не на компьютере разработчика, он не может найти эти внешние библиотеки DLL и получить к ним доступ, и я получаю следующую ошибку:

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

Внешние библиотеки DLL расположены в каталоге bin веб-сайта вместе с управляемыми библиотеками DLL, которые их содержат, и всеми другими библиотеками DLL для веб-сайта.

Поиск по этой проблеме показывает, что у многих других людей, похоже, возникает такая же проблема с доступом к внешним не.Сетевым библиотекам DLL с ASP.NET веб-сайтов, но я не нашел работающего решения.

Я попробовал следующее:

  • Запуск DEPENDS для проверки зависимостей, чтобы установить, что первые три находятся в каталоге System32 по пути, последний находится в .NET 2 framework.
  • Я поместил две библиотеки DLL и их зависимости в System32 и перезагрузил сервер, но веб-сайт по-прежнему не удалось загрузить эти внешние библиотеки DLL.
  • Предоставил полные права ASPNET, IIS_WPG и IUSR (для этого сервера) на каталог website bin и перезагрузился, но website по-прежнему не смог загрузить эти внешние библиотеки DLL.
  • Добавил внешние библиотеки DLL в качестве существующих элементов в проекты и установил для их свойства "Копировать на вывод" значение "Копировать всегда", а веб-сайт по-прежнему не может найти библиотеки DLL.
  • Также установите для их свойства "Действие сборки" значение "Встроенный ресурс" и веб-сайт по-прежнему не может найти библиотеки DLL.

Мы были бы очень признательны за любую помощь в решении этой проблемы!

Это было полезно?

Решение

Попробуйте поместить библиотеки dll в каталог \System32\Inetsrv.Это рабочий каталог для IIS на Windows Server.

Если это не сработает, попробуйте поместить библиотеки DLL в каталог System32, а файлы зависимостей - в каталог Inetsrv.

Другие советы

Это происходит потому, что управляемые библиотеки dll теневым образом копируются во временное расположение в каталоге .NET Framework.Видишь http://msdn.microsoft.com/en-us/library/ms366723.aspx для получения подробной информации.

К сожалению, неуправляемые библиотеки DLL НЕ копируются, и ASP.NET процесс не сможет найти их, когда ему потребуется их загрузить.

Одно из простых решений - поместить неуправляемые библиотеки dll в каталог, который находится в системном пути (введите "path" в командной строке, чтобы увидеть путь на вашем компьютере), чтобы их можно было найти с помощью процесса ASP.NET.Каталог System32 представляет собой всегда в path, поэтому размещение неуправляемых DLL-файлов там всегда работает, но я бы рекомендовал добавить в path какую-нибудь другую папку, а затем добавить туда DLL-файлы, чтобы предотвратить загрязнение каталога System32.Один большой недостаток этого метода заключается в том, что вам приходится переименовывать неуправляемые библиотеки dll для каждой версии вашего приложения, и вы можете быстро создать свой собственный DLL-ад.

В качестве альтернативы помещению библиотеки dll в папку, которая уже указана в path (например, system32), вы можете изменить значение path в вашем процессе, используя следующий код

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

Затем, когда LoadLibrary попытается найти неуправляемую библиотеку DLL, она также просканирует SearchPath .Это может быть предпочтительнее, чем вносить беспорядок в System32 или другие папки.

Добавляя к ответу Мэтта, это то, что, наконец, сработало для меня для 64-разрядного сервера 2003 / IIS 6:

  1. убедитесь, что ваши библиотеки dll / asp.net имеют ту же версию (32/64 разрядную)
  2. Поместите неуправляемые библиотеки DLL в каталог inetsrv (обратите внимание, что в 64-разрядной версии Windows это находится в каталоге syswow64, даже если создан каталог sys32 /inetsrv)
  3. Оставьте управляемые библиотеки dll в /bin
  4. Убедитесь, что оба набора dll-файлов имеют разрешения на чтение / выполнение

Взгляните с ФилеМон или ПрокМон и фильтруйте по именам проблемных библиотек DLL.Это покажет вам, какие каталоги сканируются в поисках DLL-файлов, и любые проблемы с разрешениями, которые у вас могут возникнуть.

Другим вариантом является внедрение собственной библиотеки DLL в качестве ресурса в управляемую библиотеку DLL.Это сложнее в ASP.NET, поскольку для этого требуется запись во временную папку во время выполнения. Техника объяснена в другом ответе SO.

Всегда стоит проверка пути переменная в настройках вашей среды тоже.

Запуск ЗАВИСИТ от XYZ.dll напрямую, в том расположении, в котором вы его развернули.Если это не выявит ничего недостающего, используйте инструмент fuslogvw в platform SDK для отслеживания ошибок загрузчика.Кроме того, журналы событий иногда содержат информацию о сбоях при загрузке библиотек DLL.

Я столкнулся с той же проблемой.И я перепробовал все вышеперечисленные опции, копируя в system32, inetpub, устанавливая path environment и т.д., Ничего не сработало.Эта проблема окончательно решается путем копирования неуправляемой библиотеки dll в каталог bin веб-приложения или веб-службы.

После того, как я весь день бился над этой проблемой, и, наконец, я нашел решение, которое меня устраивает.Это всего лишь тест, но метод работает.

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();
                  }
                }
          }
        }
    }
}

При Application_start используйте это:(настройте папки /bin/x64 и bin/dll/x64 по мере необходимости)

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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top