Inno setup:将 DLL 放在子目录中

Inno Setup: Put DLLs in a subdirectory

本文关键字:子目录 DLL setup Inno      更新时间:2023-10-16

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

  • dlls/
    • 答.dll
    • 乙.dll
  • 样本/
  • 第.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 

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

  • 是否有必要将所有 dll 放在与可执行文件相同的级别上?
  • 或者有没有办法让可执行文件在子目录 dll/中找到它的依赖项?

如果您使用的是隐式 DLL 链接,则只有几个目录您可以在其中放置必要的 DLL 文件。假设SafeDllSearchMode处于打开状态(这是自 Window XP SP2 以来的默认设置(,Windows 加载程序将按以下顺序搜索 DLL:

  1. 可执行文件所在的目录
  2. 视窗目录
  3. 视窗系统目录
  4. 当前工作目录
  5. PATH 环境变量中列出的目录

有关搜索顺序的详细信息,请参阅 https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85(.aspx

如果您使用这种类型的链接,我建议您将 DLL 放在与可执行文件相同的目录。

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

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