Наш продукт включает несколько DLLs, созданные из открытого исходного кода в файлы с именами по умолчанию, как поставили разработчики ПО с открытым исходным кодом. Мы стараемся установить файлы в наших собственных каталогах, и мы тщательно настраиваем путь поиска (только для наших процессов) для угождения загрузчику.
Другой разработчик - высокий интеллект - решил, что будет легче установить их собственную сборку части того же открытого исходного кода в C:\WINDOWS under the same default DLL filenames. Следовательно, когда мы запускаем процесс, который зависит от них DLLs с открытым исходным кодом, система ищет C:\WINDOWS before our directories and finds the DLLs installed by the other developer. И они являются, конечно, несовместимыми.
Идеи, которые произошли со мной до сих пор:
По различным причинам ни одна из этих опций не приемлема в данный момент.
Что еще мы можем сделать для защиты нас от высоких интеллектов мира?
Чтобы добавить к уже отличным ответам, у вас есть еще пара вариантов:
Предпочтительное решение этой проблемы, поддерживаемое начиная с Windows XP, - превратить вашу dll в сборку win32 (они не обязательно должны быть .NET, но документация по созданию сборок win32 со строгими именами ужасающе легка. так что легко запутаться и подумать, что это технология только для .NET).
Сборка помечается сложнее, чем папка (с именем сборки), содержащая библиотеки DLL, и .manifest (с именем сборки), который содержит элемент assemblyIdentiy, и несколько файловых узлов для каждой библиотеки DLL. в сборке.
Поиск на основе сборок работает, даже если библиотеки DLL статически связаны!
Если исполняемые файлы находятся в разных папках, то есть два способа получить доступ к общим сборкам:
Вы можете хранить свои сборки в частном альтернативном месте, если вы ожидаете, что ваше приложение будет использоваться в Windows 7 и выше. Создайте app.exe.config для каждого исполняемого файла и укажите элемент probeing privatePath на общую папку, в которой вы храните сборки.
Если вы согласны с требованием административного доступа для выполнения установки (через MSI), тогда вы можете иметь дело с ужасно плохой документацией (ну, с отсутствующей документацией), которая касается присвоения вашим сборкам строгого имени, а затем сохранить сборку в WinSxS.
Если вы не можете или не хотите объединять свои библиотеки DLL в сборки, то эта страница описывает порядок поиска DLL.
Использование таких функций, как SetDllDirectory , поможет только для загруженных библиотек DLL. динамически во время выполнения (через LoadLibrary).
Порядок поиска Dll использовался следующим образом:
Который вы могли бы использовать в своих интересах - запускать каждый exe, устанавливая «текущий» каталог на папку, содержащую библиотеки DLL OSS.
С появлением SafeDllSearchMode порядок поиска теперь следующий:
Это означает, что теперь меньше контроля, чем когда-либо :( - Еще быстрее он переходит в "ненадежные" папки c: \ windows и System32.
Опять же, если исходная dll загружается через LoadLibrary, и ее зависимые dll являются проблемой, LoadLibraryEx с флагом LOAD_WITH_ALTERED_SEARCH_PATH вызовет следующий порядок поиска (при условии, что вы передадите полный путь к LoadLibraryEx): -
У вас есть только два варианта: развернуть DLL в том же каталоге, что и EXE (именно там Windows смотрит в первую очередь) или с помощью манифестов и развернуть DLL в параллельном кэше Windows. Я не думаю, что последний вариант распространен в мире с открытым исходным кодом, но это единственное реальное решение, если вы хотите использовать библиотеки DLL между разными приложениями.
Каталог из который загруженное приложение обычно является первым каталогом, в котором выполняется поиск при загрузке библиотеки DLL. Однако вы можете использовать SetDllDirectory
, чтобы получить «альтернативный порядок поиска». В этом случае сначала выполняется поиск в каталоге, который вы указали для SetDllDirectory
.
Существует также SafeDllSearchMode
, который в определенной степени влияет на это. Включение этого параметра исключает текущий каталог из поиска.
Может быть, просто скомпилировать их в статическую библиотеку?
Почему бы и нет?
Кроме того, выполняется поиск в текущем каталоге, из которого запускается исполняемый файл. перед c: \ windows.