You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Lazarus生成的EXE仅在Windows系统目录查找version.dll?

让Lazarus生成的EXE仅从Windows系统目录加载version.dll的方案

针对编译的EXE优先在本地目录查找version.dll、而非直接调用系统目录版本的问题,以下是几种无需静态链接的解决方法:

方法1:显式加载指定系统路径的version.dll

放弃编译器自动完成的隐式链接,改为手动加载系统目录下的version.dll,完全控制加载来源:

  1. 调用GetSystemDirectory获取Windows系统目录路径;
  2. 拼接出version.dll的绝对路径;
  3. 通过LoadLibrary加载该绝对路径的DLL,再用GetProcAddress获取所需函数的地址。

示例Pascal代码:

uses
  Windows;

var
  SysDir: array[0..MAX_PATH] of Char;
  hVersionDLL: THandle;
  // 以GetFileVersionInfoSizeW为例,替换成你需要的version.dll函数
  GetFileVersionInfoSizeW: function(lptstrFilename: LPCWSTR; var lpdwHandle: DWORD): DWORD; stdcall;
begin
  // 获取系统目录
  GetSystemDirectory(SysDir, MAX_PATH);
  StrCat(SysDir, '\version.dll');
  
  // 加载系统目录下的version.dll
  hVersionDLL := LoadLibrary(SysDir);
  if hVersionDLL <> 0 then
  begin
    // 获取函数地址
    @GetFileVersionInfoSizeW := GetProcAddress(hVersionDLL, 'GetFileVersionInfoSizeW');
    if Assigned(GetFileVersionInfoSizeW) then
    begin
      // 此处添加函数调用逻辑
    end;
    // 用完释放DLL
    FreeLibrary(hVersionDLL);
  end;
end;

这种方式完全绕开系统默认的DLL搜索顺序,确保只加载系统目录的版本,同时保持动态链接的特性。

方法2:修改进程的DLL搜索路径

在程序启动初期调用SetDllDirectory函数,移除当前目录的搜索优先级,让系统直接从系统目录等标准位置查找DLL:

begin
  // 清空额外的DLL搜索目录,仅保留系统默认的系统目录、Windows目录等
  SetDllDirectory('');
  Application.Initialize;
  // 后续程序逻辑
end;

调用SetDllDirectory('')后,系统的DLL搜索顺序会跳过当前目录,直接检查系统目录,刚好解决你遇到的「先查本地再查系统」的问题。此方法无需修改现有函数调用逻辑,只需在启动时添加一行代码。

关于LOAD_WITH_ALTERED_SEARCH_PATH的说明

你提到的LOAD_WITH_ALTERED_SEARCH_PATH选项仅配合LoadLibrary的绝对路径使用,和静态链接没有关系——它只是告诉系统:以传入的DLL路径所在目录为基准进行依赖搜索,而非当前进程目录。如果采用方法1的显式加载,若version.dll还有其他依赖,可考虑使用该选项,但单纯加载version.dll本身时,直接用绝对路径加载即可生效。

内容的提问来源于stack exchange,提问作者f.verrini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:20:00