Как указано выше, я переношу приложение с Win10, VS2019 на Win11 VS2022. В среде Win11/2022 я получаю сообщение «Невозможно загрузить dll... или одну из ее зависимостей. Указанный модуль не найден». Обратите внимание, что родительское приложение — это 32-разрядное (X86) приложение vb. DLL — C++ (vs2013).
DLL полностью квалифицирована. Я запустил dumpbin против dll, и все 6 зависимостей находятся в syswow64, как и dll.
Вот объявление и вызов функции, вызывающей нарушение:
<DllImport("C:\windows\syswow64\MyFile.dll", CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function MyFile_open_device(ByVal index As Integer, ByRef errorCode As IntPtr) As Integer
End Function
В основном коде MyFile_open_device вложен в блок Try, который, в свою очередь, выдает текстовое объяснение блока Try.
Помимо вопросов, которые могут у вас возникнуть, или предложений относительно того, как диагностировать (и то, и другое приветствуется), мне интересно, известно ли кому-нибудь о каких-либо изменениях между 11 октября или 2019/2022 годами, которые могли бы вызвать это состояние.
Вот объявление и вызов функции, вызывающей нарушение:
<DllImport("C:\windows\syswow64\MyFile.dll", CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function MyFile_open_device(ByVal index As Integer, ByRef errorCode As IntPtr) As Integer
End Function
Я получаю сообщение «Невозможно загрузить dll... или одну из ее зависимостей. Указанный модуль не найден».
Хм. Не уверен, откуда вы взяли, что библиотеки DLL не следует устанавливать в папки Windows. Каждый случай индивидуален. В этом случае рассматриваемая dll ссылается на несколько других dll, которые установлены MS и могут быть доступны или недоступны в зависимости от конфигурации машины. Не разрывая целевую платформу установки, лучше всего установить ее в месте с лучшим доступом ко всем целям. В этом случае все необходимые библиотеки MS dll установлены в Windows. В частности, в Windows «лучшим случаем» является тот, который лучше всего переносит сбои.
Идея пришла мне от MS, который говорит, что все в дереве папок Windows принадлежит ОС, поэтому пользователям, не являющимся администраторами, не разрешено писать туда. На какой планете вы жили с момента появления UAC (вообще, до этого - когда вышла Win85, были и Power Users и ограниченные права)? Если DLL не является частью ОС, ей не место в папках ОС.
Я обнаружил, что большинство требований MS в этом отношении в лучшем случае бесполезны, а чаще всего вредны при установке программного обеспечения в средах клиентов. Это потому, что клиенты часто удивительно изобретательны (ирония) в отношении структур файловой системы, которые они развертывают, и просто головокружительны в использовании PATH(ов). Таким образом, хотя основной исполняемый файл нашего приложения может работать в любом месте, различные компоненты, которые сильно зависят от MS, неохотно страдают от креативности файловой системы. Мы используем этот подход с 2010 года. Он установлен на производственных и государственных объектах по всему миру. Мне никогда не звонят в службу поддержки.
Ерунда. Если вы используете правильный установщик, клиент не имеет никакого отношения к PATH или расположению файлов, а библиотеки DLL, используемые вашим приложением и находящиеся в каталоге вашего собственного приложения, в любом случае не нужно добавлять в PATH - это в первую очередь. который ищется при загрузке DLL. Причиной добавления ограничения является замена вредоносным ПО файлов в системных папках, и вы должны защищать своих клиентов, а не подвергать их риску. Если они устанавливают программное обеспечение, вы заставляете их нарушать безопасность ОС и оставлять в ней зияющие дыры, и это безответственно с вашей стороны.
И тот факт, что вы используете неправильную методологию более десяти лет, не говорит в пользу практики вашей компании или ее заботы о своих клиентах.
Привязки загрузчика (доступные из утилиты gflags, которая распространяется как часть Windows SDK) — это мой инструмент для отладки сбоев загрузки DLL вместе с файлом depend.exe. Вы проверили шесть непосредственных зависимостей, но не проверили их зависимости. Выдача ошибок по умолчанию при сбоях загрузки чрезвычайно кратка и имеет тенденцию вводить в заблуждение.
Хорошая находка Крейга. Спасибо за это. В этом случае я обнаружил недопустимые зависимости, но отмечу, что одна из моих тем на SO содержит другое, более полное решение.





Вы перевели проект на x86?
Вы не можете использовать «ЛЮБОЙ ЦП», поскольку vs2022 — это ПЕРВАЯ версия VS с 64-разрядной архитектурой.
Итак, когда вы создадите и запустите, у вас будет 64-разрядный проект при использовании ЛЮБОГО ЦП. Предыдущие версии VS означали, что ЛЮБОЙ ЦП приводил к запуску и запуску 32-битной версии по умолчанию, поскольку любая версия vs до vs2022 была 32-битной версией.
Теперь, когда vs2022 имеет 64-битную версию, тогда ЛЮБОЙ ЦП по умолчанию приводит к тому, что ваш проект работает как 64-битная версия, и поэтому они не могут использовать 32-битные библиотеки DLL.
Следовательно, выберите (заставьте) проект работать как x32 бита отсюда:
В дополнение к вышесказанному я должен сказать, что файлы .dll в папке c:\windows были заблокированы в течение многих лет, и поэтому часто такие файлы .dll блокируются или даже перехватываются программным обеспечением для сканирования на вирусы. А чтобы скопировать такие файлы в системную папку, вам потребуются повышенные права (следовательно, это место действительно не идеально для ваших пользовательских dll).
Даже проекты, предшествующие vs2022, должны принудительно настраивать параметры ЦП, поскольку, если ваш код и зависимости не могут работать как x64 или x32-разрядные (все .net-коды .dll), то оставляя это на волю случая и используя ЛЮБОЙ ЦП, вы плохо представляете, как с каким битовым размером будет работать ваше приложение.
В вашем случае, поскольку это x32-разрядные dll, вам необходимо заставить ваш проект работать как x86, а ЛЮБОЙ ЦП по умолчанию теперь приводит к созданию x64-разрядной программы, а не x32 (что было результатом по умолчанию при использовании версий VS до vs2022.
Я бы переместил эти .dll, а также щелкнул по ним правой кнопкой мыши и убедился, что они разблокированы, поскольку .net не будет использовать такие .dll, если они были, например, загружены из Интернета. Фактически, даже при загрузке zip-файла с примером кода и .dll в этом zip-файле? При распаковке файлы блокируются и не могут быть использованы .net.
Поэтому вам необходимо убедиться, что вы разблокировали zip-файл перед распаковкой, поскольку любые .dll-файлы внутри этого zip-архива также будут помечены как заблокированные и небезопасные.
Итак, разблокируйте zip-файл перед распаковкой. Или после разархивирования разблокируйте все файлы и .dll в этой разархивированной папке.
Отсюда такой вариант:
Хороший. Кажется, это не самая важная проблема, но она привела меня в правильном направлении. Я продолжу позже.
Ваш бит заставил меня посмотреть имена файлов поддержки драйверов, которые использует MS... по сравнению с тем, что они использовали раньше. (Если у вас от этого не потеют ладони...) Я упал на это, когда забирался в высокую траву, окружающую файловую систему безопасности. Оказывается, MS может потребовать от вас установить среду выполнения MSVC++ для... подождите... ПРЕДЫДУЩЕЙ версии, даже если у вас есть все необходимое для последних двух версий на вашем текущем компьютере. По-видимому, это считается гораздо лучшей идеей, чем просто сделать старые файлы обратно совместимыми.
В частности, решением было установить среду выполнения C++ из версии MSVC 2013 года. Работает как чемпион. В конце концов я попытаюсь обновить вызывающую ошибку DLL, однако это сторонняя библиотека, и я не хочу ничего разбирать, пока у меня не будет времени сделать это правильно/сделать все необходимые ошибки.
Вам не следует помещать свои библиотеки DLL в папку Windows. Он должен находиться либо в папке вашего приложения, либо в папке в Windows PATH. См. документацию для функции Win32 LoadLibrary(), чтобы узнать о папках, в которых осуществляется поиск по умолчанию.