5

函数是否LoadLibraryEx使用并排清单?我有带有嵌入式 SxS 清单的 bar.dll,并且该清单描述了此 bar.dll 的版本,其他 dll 文件 foo.dll 具有将 bar.dll 列为依赖项的清单,并具有指定的版本。但是,当我尝试从 foo.dll 加载 bar.dll 时,LoadLibraryEx("bar.dll", NULL, 0)我看到(启用了带有 gflags 的 sls)它忽略了这些清单,并加载它在搜索路径中看到的 bar.dll 的第一个版本,如果我定义ISOLATION_AWARE_ENABLED并使用LoadLibrary它发现正确的版本,但这ISOLATION_AWARE_ENABLED不会影响 的行为LoadLibraryEx,我需要加载正确的版本,LoadLibraryEx因为LoadLibraryEx隐式用于延迟加载 dll。应该像这样LoadLibraryEx工作,还是我的项目配置有问题?

富dll

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="foo" version="0.1.2.3" type="win32"/>
<dependency>
    <dependentAssembly>
        <assemblyIdentity name="bar" version="0.1.2.3" type="win32" />
    </dependentAssembly>
</dependency>
<file name="foo.dll">
</file>
</assembly> 

bar.dll

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="bar" version="0.1.2.3" type="win32"/>
<file name="bar.dll">
</file>
</assembly> 
4

1 回答 1

8

LoadLibrary使用调用线程的活动激活上下文。但这是什么背景?为什么一定是你的foo.dll?为什么不来自xyz.dll或来自 exe ?实际上,大多数时候活动激活上下文正是来自 exe。

如果 dll 有自己的清单 - 系统为此 dll 创建激活上下文并保存它(直到 dll 将被卸载)但不使其处于活动状态。这很明显 - 我们有多个 dll 在处理中,但只有一个活动上下文 - 从哪个 dll 中选择它?从exe。但是系统在调用入口点之前激活(使其当前处于活动状态)dll 激活上下文。并在入口点返回后将其停用。但是在另一个 dll 函数中说 - (谁叫它?)上下文已经不是来自你的 dll。

所以解决方案必须是下一个:

在dll中定义2个全局变量:

BOOL gActCtx;
HANDLE ghActCtx

DLL_PROCESS_ATTACH保存当前激活上下文(它来自您的 dll 清单)

gActCtx = GetCurrentActCtx(&ghActCtx);

释放它DLL_PROCESS_DETACH

if (gActCtx) ReleaseActCtx(ghActCtx);

当您需要加载时,请bar.dll执行以下操作:

if (gActCtx)
{
    ULONG_PTR Cookie;

    if (ActivateActCtx(ghActCtx, &Cookie))
    {
        LoadLibraryExW(L"bar.dll", NULL, 0);

        DeactivateActCtx(0, Cookie);
    }
}
于 2018-01-17T19:48:19.820 回答