Inno Setup: поместите DLL в подкаталог

Я хочу скопировать зависимости (пару файлов DLL) в отдельный подкаталог. После установки моей программы структура каталогов будет выглядеть так:

  • DLLs /
    • A.DLL
    • B.dll
  • образец/
  • pg.exe

Соответствующая часть моего сценария выглядит следующим образом:

[Dirs]
Name: "{app}\sample"Name: "{app}\dll"[Files]
Source: "pg.exe"; DestDir: "{app}"; Flags: ignoreversion
; icon file
;Source: "pg.ico"; DestDir: "{app}"; sample ini and geoemtry file
Source: "geometry.xml"; DestDir: "{app}\sample"Source: "ini.xml"; DestDir: "{app}\sample"
; DLL
Source: "a.DLL"; DestDir: "{app}\dll"; Flags: onlyifdoesntexist
Source: "b.DLL"; DestDir: "{app}\dll"; Flags: onlyifdoesntexist

Когда я тестирую мой установщик в виртуальной машине, я получаю сообщение об ошибке, в котором говорится, что a.DLL не найден. Проблема быстро решается, если я просто копирую a.DLL от dll/ в каталог исполняемого файла.

  • Нужно ли ставить все библиотеки на один уровень с исполняемым файлом?
  • Или есть способ заставить исполняемый файл найти свои зависимости в подкаталоге dll /?

2

Решение

Если вы используете неявное связывание DLL, то существует только несколько каталогов
где вы можете разместить необходимые файлы DLL. Если предположить, SafeDllSearchMode включен (это значение по умолчанию начиная с Windows XP SP2), загрузчик Windows выполняет поиск DLL в следующем порядке:

  1. Каталог, в котором расположен ваш исполняемый файл
  2. Каталог Windows
  3. Системный каталог Windows
  4. Текущий рабочий каталог
  5. Каталоги, перечисленные в переменной среды PATH

Для получения дополнительной информации о порядке поиска см. https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx

Если вы используете этот тип связи, я бы посоветовал вам поместить ваши DLL в
тот же каталог, что и ваш исполняемый файл.

С другой стороны, если вы явно ссылаетесь на эти DLL с помощью LoadLibrary или же
LoadLibraryEx API, вот что вы можете сделать:

  1. Ты можешь позвонить AddDllDirectory и передайте ему путь к каталогу, который содержит ваш
    Библиотеки DLL. Убедитесь, что вы вызываете эту функцию, прежде чем загружать библиотеки, и убедитесь, что вы
    загрузить библиотеки с помощью LoadLibraryEx с флагом LOAD_LIBRARY_SEARCH_USER_DIRS,
  2. Вы можете получить путь к вашему исполняемому файлу, используя GetModuleFileName функция, то
    используйте его для построения абсолютных путей к DLL и используйте эти пути при вызове LoadLibrary(Ex),
  3. Ты можешь позвонить SetDllDirectory перед звонком LoadLibrary(Ex), Проблема с этим
    Метод заключается в том, что каждый раз, когда SetDllDirectory функция вызывается, она заменяет каталог
    указано в предыдущем SetDllDirectory вызов. Это может вызвать проблемы, если вы не будете осторожны
    потому что какая-то другая часть кода может вызвать SetDllDirectory и вызвать сбой при загрузке ваших DLL
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]