问题描述
我想将依赖项(几个DLL文件)复制到一个单独的子目录中。安装程序后,目录结构如下:
I want to have the dependencies (a couple of DLL files) copied in a separated sub directory. After installing my program, the directory structure would look like:
- dlls /
- a.dll
- b.dll
我脚本的相关部分如下:
The relevant part of my script is as follows:
[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.DLL
从dll /
复制到可执行文件的目录,就可以快速解决该问题。When I test my installer in a VM I get an error saying that a.DLL is not found. The problem is quickly solved if I just copy
a.DLL
fromdll/
to the directory of the executable.- 是否有必要将所有dll与可执行文件置于同一级别?
- 或者是否有办法使可执行文件在子目录dll /中找到其依赖项?
推荐答案
如果使用隐式DLL链接,则只有几个目录
可在其中放置必要的DLL文件。假设SafeDllSearchMode
处于打开状态(这是Window XP SP2以来的默认设置),Windows加载程序将按以下顺序搜索DLL:If you are using implicit DLL linkage, then there are only several directorieswhere you can place the necessary DLL files. Assuming
SafeDllSearchMode
is on (which is the default since Window XP SP2), Windows loader searches DLLs in this order:- 可执行文件所在的目录
- Windows目录
- Windows系统目录
- 当前工作目录
- PATH环境变量中列出的目录
- The directory where your executable located
- The Windows directory
- The Windows system directory
- The current working directory
- The directories listed in the PATH environment variable
有关搜索顺序的更多信息,请参见
For more information about search order see https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx
如果使用这种类型的链接时,建议您将DLL与可执行文件放在
相同的目录中。If you are using this type of linkage, I would suggest you place your DLLs in thesame directory as your executable.
另一方面,如果您显式使用
LoadLibrary
或
LoadLibraryEx
API链接到这些DLL,这是您可以做的:On the other hand, if you are explicitly linking to these DLL using
LoadLibrary
orLoadLibraryEx
APIs, here is what you can do:- 您可以调用
AddDllDirectory
并将路径传递给包含
DLL的目录。确保在加载库之前调用此函数,并确保使用标记为LOAD_LIBRARY_SEARCH_USER_DIRS $的
LoadLibraryEx
来加载
。 c $ c>。 - 您可以使用
GetModuleFileName
函数检索可执行文件的路径,然后
使用它来构造DLL的绝对路径,并在调用LoadLibrary(Ex)
时使用这些路径。 - 您可以调用
SetDllDirectory
,然后调用LoadLibrary(Ex)
。此
方法的问题在于,每次调用SetDllDirectory
函数时,它将替换上一个中指定的目录
调用。如果您不小心
。 SetDllDirectory
,这可能会导致问题,因为代码的其他部分可能会调用SetDllDirectory
并在加载DLL时导致失败
- You can call
AddDllDirectory
and pass it the path to directory that contains yourDLLs. Make sure you call this function before you load the libraries, and make sure youload the libraries usingLoadLibraryEx
with flagLOAD_LIBRARY_SEARCH_USER_DIRS
. - You can retrieve the path to your executable using
GetModuleFileName
function, thenuse it to construct absolute paths to DLLs and use these paths when callingLoadLibrary(Ex)
. - You can call
SetDllDirectory
before callingLoadLibrary(Ex)
. The problem with thismethod is that each time theSetDllDirectory
function is called, it replaces the directoryspecified in the previousSetDllDirectory
call. This can cause problems if you are not carefulbecause some other part of code could callSetDllDirectory
and cause failure when loading your DLLs
这篇关于Inno Setup:将DLL放在子目录中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!