我有两个应用程序并安装在不同的文件夹中,我们称之为app A和B,A是主应用程序,B是COM模块,A启动后将通过COM API启动B,有些DLL需要由B加载当B开始时,如果我通过双击A的快捷方式启动A,一切都没问题,但如果我安装A,并通过检查安装的最后一个对话框中的启动A选项启动A,则启动B,但是其中一个DLL加载失败,错误代码为126(ERROR_MOD_NOT_FOUND),如果我通过双击快捷方式再次退出并重新启动,则会再次运行。
已经做了一些谷歌似乎从快捷方式开始和安装之间的唯一区别是当前目录,即,如果从安装选项开始,与从cmd开始的安装程序包文件夹一样开始,如打开cmd,切换到安装程序包的文件夹,然后以完整路径启动应用程序A,我试过这个,也运行良好。
我的安装程序包由installshield构建。
有没有人有关于这个问题的线索?
//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"");
的调用。根据一些quick research,这应该只对子进程中隐式加载的DLL有影响,但是没有似乎是您描述的场景。
您已尝试通过显式添加目录来撤消此调用;这是我推荐的(但未经测试的)选项2和3:
SetDllDirectory
所述,请调用SetDllDirectory(NULL)
恢复默认搜索顺序,或AddDllDirectory
添加您的文件夹,然后调用LoadLibraryEx(..., LOAD_LIBRARY_SEARCH_USER_DIRS)