Как я могу отложить загрузку частной сборки Windows? Является ли это возможным?

Мой проект - это подключаемый модуль (Windows DLL), который загружается исполняемым файлом хоста, не находящимся под моим контролем. Моя DLL хочет загрузить дополнительные библиотеки. Я делаю это с частными собраниями; есть отличный ответ на как может ли плагин приложения Win32 загрузить свою DLL в свой собственный каталог, чтобы узнать, как это сделать. Но если я добавлю /delayload dependentlib.dll в строку ссылки основной DLL, чтобы избежать загрузки сборки до тех пор, пока она не понадобится (я вынужден делать это по разным причинам), Windows больше не будет искать мои частные сборки - похоже, она игнорирует манифест, который я скомпилировал. Вместо этого он ищет загруженную с задержкой DLL в обычном пути поиска. (Я использую sysinternals procmon, чтобы проверить это.)

Это известная ошибка или есть другой способ отложить загрузку сборки? Я бы предпочел не идти по маршруту LoadLibrary + GetProcAddress, где мне нужно знать все символы, которые меня интересуют в зависимой библиотеке.


person GaryO    schedule 16.02.2011    source источник


Ответы (2)


Проблема здесь в том, что при первом вызове функции отложенной загрузки контекст активации приложения по умолчанию является текущим контекстом.

Вам нужно создать контекст активации: CreateActCtx, указывающий на ваш собственный манифест (я думаю, возможен hinstance + resource id).

Затем оберните весь или хотя бы самый первый вызов dll с помощью ActivateActCtx (и соответствующая функция деактивации), чтобы обеспечить поиск правильных сборок.

Теоретически вы можете просто встроить код для активации соответствующего контекста в помощник функция.

person Chris Becke    schedule 16.02.2011
comment
Спасибо - отлично сработало. Вы правы, все, что вам нужно, это hmodule и идентификатор ресурса (2). После этого все, что нужно, - это перенести первый вызов в зависимую dll. Спасибо огромное! - person GaryO; 23.02.2011

К сожалению, такое поведение является преднамеренным. По сути, когда вы указываете / DELAYLOAD, вы просто инструктируете компоновщик вставить для вас вызовы LoadLibrary и GetProcAddress. В результате поведение при отложенной загрузке библиотеки DLL такое же, как при динамической загрузке этой библиотеки с помощью LoadLibrary.

MSDN описывает некоторые последствия. С другой стороны, вы можете переопределить поведение по умолчанию. Я бы рекомендовал написать свою собственную вспомогательную функцию отложенной загрузки.

FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd, FARPROC * ppfnIATEntry)
{
    //...
}

Компоновщик будет вставлять вызовы этой функции всякий раз, когда ему нужно разрешить точку входа в загруженной с задержкой DLL. В вашей версии может быть реализован пользовательский поиск ваших частных сборок. Вот дополнительная информация о вспомогательной функции в MSDN.

person Peter Ruderman    schedule 16.02.2011