【问题标题】:Get current executable directory fails under test harness在测试工具下获取当前可执行目录失败
【发布时间】:2012-02-11 16:47:31
【问题描述】:

我的应用程序使用LoadLibraryGetProcAddressFreeLibrary 实现了某种插件架构。由于我所有的 dll 都与可执行文件位于同一目录中,因此当我查找 dll 时,我会使用此函数获取可执行文件的目录并在那里搜索:

string FileSystem::GetPathToProgramDirectory(){
    char progname[MAX_PATH];
    GetModuleFileNameA( NULL, progname, MAX_PATH );
    PathRemoveFileSpecA( progname );
    return string( progname );
}

这适用于生产,但是当我尝试在使用 NUnit 的集成测试下运行它时,可执行目录最终是 NUnit 的,因此加载失败。 请记住,这是非托管 C++;在托管 C++ 中,我使用 Path::GetDirectoryName(Assembly::GetExecutingAssembly()->Location) 解决了这个问题,这在这两种情况下都适用,但非托管案例让我很困惑。是否有与之对应的非托管 Winapi?

【问题讨论】:

    标签: c++ windows unit-testing dll directory


    【解决方案1】:

    这里的问题是GetModuleFileName 带有NULL 第一个参数为您提供当前运行代码的可执行文件 的路径,而您需要特定模块 那就是运行代码。因此,当您在 NUnit 下运行代码时,您最终会得到测试工具可执行文件,而不是您所期望的。

    您真正想要的是获取当前正在执行的模块的句柄,然后将其传递给GetModuleFileNameThis StackOverflow post 详细介绍了获取当前执行模块句柄的多种方法。

    将当前模块句柄与您当前拥有的代码结合起来,这应该都可以在 NUnit 下工作。

    【讨论】:

    • 当模块句柄被传递到DllMain 中的 DLL 时,我总是希望记住它。
    • @David:好点,我很惊讶在那篇 SO 帖子中也没有提到这一点。对于@dario_ramos:查看您的DllMain 入口点(msdn.microsoft.com/en-us/library/windows/desktop/…),其中第一个参数是您的DLL 句柄。
    • @dario_ramos:我可能误解了你的意思。这是我的回顾:您有一些代码(您的问题中的代码)存在于一些 DLL 中,这些 DLL 控制/管理在其他 DLL 中实现的插件,这些 DLL 位于相对于控制器/管理器 DLL 的某个目录中。如果是这种情况,您可以获取控制器/管理器 DLL 的句柄(通过我链接到的 SO 帖子,或通过 David 的方法),通过 GetModuleFileName 获取它的完整路径,然后执行您需要的任何操作你的插件目录...
    • @dario_ramos: ...(续)如果您使用David的方法,您只需添加或修改您的控制器/管理器DLL的DllMain方法来存储第一个参数(DLL模块句柄)。然后,当需要查找插件目录时,可以使用该模块句柄获取插件目录的完整路径。
    • 我自己才发现这一点(这就是我删除评论的原因)。我有点困了:P 帖子中的解决方案似乎更可重用(不要强迫客户实施 DllMain),但 DllMain 解决方案避免两次要求 HMODULE ......所以我在想我应该使用哪个,但现在毫无疑问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2011-01-18
    • 2020-10-14
    • 2018-06-18
    • 1970-01-01
    • 2020-06-03
    相关资源
    最近更新 更多