2011-02-16 85 views
7

我想要完成它描述的内容here,但接受的解决方案对我无效。我想,其原因解释here在同一进程中加载​​2个版本的相同DLL

如果具有依赖性的DLL被指定一个完整路径,系统 搜索DLL的依赖DLL ,好像他们是装有只是他们 模块名加载 。

如果用相同的模块名称DLL被 已经加载到内存中,系统只 检查重定向和 清单解决的 加载的DLL,无论是在哪个目录 前,系统不不是搜索 的DLL。

我希望我的应用程序在以下结构中。

c:\Exe 
| 
|----- c:\DLL\DLL.dll, c:\DLL\common.dll 
| 
|----- c:\DLL2\DLL2.dll, c:\DLL2\common.dll 

我的EXE将通过

LoadLibrary("c:\\DLL\\DLL.dll"); 
LoadLibraryEx("c:\\DLL2\\DLL2.dll"); 
共同

加载DLL文件在两种情况下是隐式加载。

我试过SetDllDirectory选项,但总是只有一个common.dll加载。

我在common.dll中添加了版本信息。 c:\ DLL \ common.dll具有版本2.0.1.0而c:\ DLL2 \ DLL2.dll具有版本4.0.1.0

我嵌入下面的清单与相应的版本信息,但它没有帮助。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type="win32" name="common" version="4.0.1.0" processorArchitecture="x86"></assemblyIdentity> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

有没有解决这个问题的方法?

回答

6

你在哪里嵌入了清单? EXE或DLL?

您有两种基本的方式来做到这一点,都涉及到通过为其创建清单来将“通用”转换为私有SxS程序集。

然后:

  1. 如果DLL和DLL 2包含清单列出依赖程序,那么你需要一个dependentAssembly添加到他们的清单指定“acme.common”(例如)的依赖程序集。由于依赖程序集总是在默认情况下在加载模块文件夹中进行搜索,因此每个DLL都会加载它自己的本地通用公用程序副本。

  2. 如果您只是依靠应用程序的默认激活上下文来完成大部分繁重的工作,那么您可以尝试使用ActivationContext API。 拨打CreateActCtx两次,指定两个不同的文件夹作为结果上下文的基础文件夹。

在伪代码:

HACTCTX h1 = CreateActCtx(... for DLL ...); 
HACTCTX h2 = CreateActCtx(... for DLL2 ...); 

ActivateActCtx(h1,...); 
LoadLibrary("C:\\DLL\\DLL1.DLL"); 
DeactivateActCtx(); 
ActivateActCtx(h2,...); 
LoadLibrary("C:\\DLL2\\DLL2.DLL"); 
DeactivateActCtx... 

如果DLL文件已经包含自己的舱单系统将使用这些。如果没有,这将让你指定一个私人程序集的搜索目录,而不用修改DLL本身。


要实现方案1: 首先,我不建议尝试使用DLL名称作为集名称。因此,创建一个清单,看起来像这样每个文件夹中:

<!-- acme.common.manifest --> 
<assembly manifestVersion="1.0"> 
    <assemblyIdentity type="Win32" name="acme.common" version="1.0.0.0" processorArchitecture="x86"/> 
    <file name="common.dll"/> 
</assembly> 

您可以修复的版本号,以每个文件夹中匹配common.dll的版本,但是那并不重要。

然后,要么清单你列出,或者如果你正在使用Visual Studio这样的指令

#pragma comment(linker, "/manifestdependency:\"acme.common'"\ 
        " processorArchitecture='*' version='1.0.0.0' type='win32'\"") 

只要确保依赖程序集的版本匹配相应的“acme.common”装配的版本。

+0

谢谢。我将清单嵌入到DLL中。所以,它看起来像我做你在1推荐。或者我错过了什么?清单是否正确? – PeeWee2201 2011-02-16 15:59:30

相关问题