Inno Setup:将 DLL 放在子目录中

Inno Setup: Put DLLs in a subdirectory

我想将依赖项(几个 DLL 文件)复制到一个单独的子目录中。安装我的程序后,目录结构如下所示:

我脚本的相关部分如下:

[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 

当我在 VM 中测试我的安装程序时,我收到一条错误消息,提示未找到 a.DLL。如果我只是将 a.DLLdll/ 复制到可执行文件的目录,问题很快就解决了。

如果你使用的是隐式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 放在 与您的可执行文件相同的目录。

另一方面,如果您使用 LoadLibrary 显式链接到这些 DLL 或 LoadLibraryEx API,您可以执行以下操作:

  1. 您可以调用 AddDllDirectory 并将包含您的目录的路径传递给它 DLL。确保在加载库之前调用此函数,并确保 使用带有标志 LOAD_LIBRARY_SEARCH_USER_DIRS.
  2. LoadLibraryEx 加载库
  3. 您可以使用 GetModuleFileName 函数检索可执行文件的路径,然后 用它来构造 DLL 的绝对路径,并在调用 LoadLibrary(Ex).
  4. 时使用这些路径
  5. 您可以在调用 LoadLibrary(Ex) 之前调用 SetDllDirectory。这个问题 方法是每次调用SetDllDirectory函数时,替换目录 在之前的 SetDllDirectory 调用中指定。如果您不小心,这可能会导致问题 因为代码的其他部分可能会调用 SetDllDirectory 并在加载 DLLs
  6. 时导致失败