LoadLibraryEx 忽略并排清单 [英] LoadLibraryEx ignores side-by-side manifest

查看:21
本文介绍了LoadLibraryEx 忽略并排清单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Does LoadLibraryEx function use side-by-side manifests? I have bar.dll with embedded SxS manifest, and that manifest describes version of this bar.dll, other dll file foo.dll has manifest that lists bar.dll as dependency, with specified version. But when I try to load bar.dll from foo.dll with LoadLibraryEx("bar.dll", NULL, 0) I see (with enabled sls with gflags) that it ignores these manifests, and loads first version of bar.dll that it sees in searchpath, if I define ISOLATION_AWARE_ENABLED and use LoadLibrary it finds right version, but this ISOLATION_AWARE_ENABLED doesn't affect behaviour of LoadLibraryEx, I need to load right version with LoadLibraryEx because LoadLibraryEx is used implicitly for delayed loading of dll's. Is LoadLibraryEx supposed to work like this, or is it some problem in my project configuration?

foo 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> 

推荐答案

LoadLibrary 使用了调用线程的活动激活上下文.但这是什么背景?为什么它必须来自您的 foo.dll ?为什么不从 xyz.dll 或从 exe ?大多数时候,活动激活上下文正是来自 exe.

LoadLibrary used active activation context of the calling thread. but which is this context ? why it must be from your foo.dll ? why not from xyz.dll or from exe ? really most time active activation context was exactly from exe.

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

if dll have own manifest - system create activation context for this dll and save it (until dll will be unloaded) but not make it active. and this is obviously - we have multiple dlls in process, but active context only one - from which dll select it ? from exe. however system activate (make it current active) dll activation context before call it entry point. and deactivate it after entry point return. but say inside another dll functions - (who called it ?) the context already not from your dll.

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

so solution must be next:

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

define 2 global variables in dll:

BOOL gActCtx;
HANDLE ghActCtx

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

on DLL_PROCESS_ATTACH save current activation context (it from your dll manifest)

gActCtx = GetCurrentActCtx(&ghActCtx);

DLL_PROCESS_DETACH

if (gActCtx) ReleaseActCtx(ghActCtx);

当您需要加载 bar.dll 时,请执行下一步:

and when you need load bar.dll do next:

if (gActCtx)
{
    ULONG_PTR Cookie;

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

        DeactivateActCtx(0, Cookie);
    }
}

这篇关于LoadLibraryEx 忽略并排清单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆