2016-02-10 5 views
2

Я хочу, чтобы зависимости (несколько DLL-файлов) копировались в отдельный подкаталог. После установки моей программы, структура каталогов будет выглядеть следующим образом:Inno Setup: поместить 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 

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

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

Вы используете явную или неявную DLL связи? –

+0

Не знаю. Как узнать? – Tengis

+0

Явная связь достигается с помощью 'LoadLibrary' или' LoadLibraryEx' в коде, неявная связь достигается с помощью операторов 'dllimport' /' dllexport', а библиотеки DLL должны иметь соответствующие файлы библиотеки импорта (.LIB). См. Мой ответ для более подробной информации. –

ответ

1

Если вы используете неявную связь DLL, то есть только несколько каталогов , где вы можете разместить необходимые файлы DLL. Предполагая, что SafeDllSearchMode включен (который по умолчанию, так как Window 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
+0

Спасибо, что указали места, где нужно разместить DLL. Это помогло. У меня имплицитная связь. – Tengis

+0

В списке заказов используется 'SafeDllSearchMode = 0 (off)', в то время как по умолчанию используется '1 (on)' с Windows XP SP2. – MSalters

+0

@MSalters Мой ответ не предполагал, что это был точный порядок, он просто указывал места. Однако я обновлю ответ, чтобы избежать путаницы. –

Смежные вопросы