如果应用程序从安装选项启动,则加载库失败,错误代码为 126



我有两个应用程序并安装在不同的文件夹中,我们称之为应用程序A和B,A是主应用程序,B是COM模块,A启动后A将通过COM API启动B,有一些DLL需要由B加载而B启动,如果我双击A的快捷方式启动A, 一切都很好,但是如果我安装 A,并通过检查安装最后一个对话框中的启动 A 选项来启动 A,则 B 已启动,但其中一个 DLL 加载失败,错误代码为 126 (ERROR_MOD_NOT_FOUND),如果我退出并通过双击快捷方式再次重新启动,它会再次工作。

已经做了一些谷歌,似乎从快捷方式开始和安装之间的唯一区别是当前目录,即,如果从安装选项开始,与使用 cmd 从安装包文件夹启动相同,例如打开 cmd,切换到安装程序包的文件夹,然后使用完整路径启动应用程序 A,我试过这个,也运行良好。

我的安装程序包是由安装盾构建的。

有人对这个问题有一些线索吗?

  1. 已经尝试将当前目录切换到A和B的安装路径,两者都无法解决此问题。
  2. 已经尝试将dll目录设置为B的安装路径,这也是失败DLL的路径,也不起作用。
  3. 已经尝试使用完整路径加载DLL,也失败了。
//SetCurrentDirectory(L"C:Program Files (x86)install path of A"); <<<not work
//SetCurrentDirectory(L"C:Program Files (x86)install paht of B");   <<<not work
//SetDllDirectory(L"C:Program Files (x86)DLL path");   <<<not work
//m_hLibrary = LoadLibrary((LPCWSTR)DLL full path);   //not work
m_hLibrary = LoadLibrary((LPCWSTR)dllName.c_str());   //failed with error code 126

听起来你已经诊断出了症状。解决这些问题可能很棘手,因为至少某些版本的 InstallShield 调用 API 会降低在建立应用程序文件夹之前加载意外 DLL 的能力。当您直接从安装程序启动进程时,这些调用的效果似乎会延续到您的进程中。

因此,首先,过度简化的选项 1:从向导的最后一页删除启动应用的选项。噗,问题消失了。但这可能会让别人不高兴。

相反,让我们尝试深入了解正在发生的事情。根据 InstallShield 的确切版本,它可能会调用 API 的某种组合,但最有可能的罪魁祸首是对SetDllDirectory(L"");根据一些快速研究,这应该只对子进程中隐式加载的 DLL 产生影响,但这似乎不是您描述的方案。

您已经尝试通过显式添加目录来撤消此调用;以下是我推荐的(但未经测试的)选项 2 和 3:

  • SetDllDirectory中所述,调用SetDllDirectory(NULL)以恢复默认搜索顺序,或
  • 调用 SetDllDirectory 或AddDllDirectory添加文件夹,然后调用LoadLibraryEx(..., LOAD_LIBRARY_SEARCH_USER_DIRS)

最新更新