如何将第三方Windows DLL组织到我的应用程序文件夹中的子文件夹中?

问题描述:

我们有一个应用程序依赖于许多第三方DLL组。不幸的是,这些第三方DLL的编写者都没有对它们进行非常一致的命名,所以很难看出哪个DLL是什么组的一部分。如何将第三方Windows DLL组织到我的应用程序文件夹中的子文件夹中?

为了尝试和管理这个,我们希望将第三方DLL组放在应用程序文件夹的一个文件夹中,而不是像这样在应用程序旁边。

--> Application Folder 
    --> Application.exe 
    --> MyDLL1.dll 
    --> MyDLL2.dll 
    --> Third Party 1 DLL folder 
     --> Third Party 1 DLL 1.dll 
     --> Third Party 1 DLL 2.dll 
     --> Third Party 1 DLL 3.dll 
    --> Third Party 2 DLL folder 
     --> Third Party 2 DLL 1.dll 
     --> Third Party 2 DLL 2.dll 
     --> Third Party 2 DLL 3.dll 

我的问题是如何让动态链接器找到它们并加载它们?

我们可以使用LoadLibrary()和GetProcAddress()手动执行此操作,但这非常繁琐。看起来我们可以用清单和“探索”来做到这一点,但是这似乎只是Windows 7(我们需要在XP及更高版本上工作)。

更新

我们用来体现这样做到底(感谢@克里斯) - 有一对夫妇,我们必须在任何情况下,通过跳是寻找一个解决方案的其他箍!

首先,我们的“程序集”实际上有几个DLL,我们链接到一个链接,然后链接到其他链接。所有这些DLL都需要将程序集依赖项添加到它们的清单中(可以使用mt.exe来执行此操作,而无需访问这些DLL的源代码)。

其次,程序集需要与DLL并行,而不是与EXE一起 - 我们的DLL实际上是一个已经在应用程序子文件夹中的插件。

这里是我们的最终布局:

--> Application Folder 
    --> Application.exe 
    --> Plugins folder 
     --> MyDLL1.dll 
     --> Third Party 1 
      --> Third Party 1.manifest 
      --> A.dll 
      --> B.dll 
      --> C.dll 

如果MyDLL1.dll是一个插件,链接到A.DLL,并A.DLL链接到两个B.DLL和C.dll,则:

  1. “第三方1.manifest”需要包括所有A.DLL,B.DLL和C.dll作为一个组件
  2. “MyDLL1.dll”需要在其清单中的“第三方1”或依赖项动态链接程序不会找到A.dll
  3. A.dll需要其清单中的依赖项条目为“第三方1”或动态链接程序不会找到B.dll和C.dll
  4. “第三方1”文件夹需要与“MyDLL1.dll “,不是旁边的”Application.exe“

对我而言,(3)有点刺激。你会认为链接器会在程序集中寻找依赖的DLL。

您可以使用清单而不探测。 通过定义包含dll的.manifests创建“假”程序集。 (在这个dll中没有修改) 由于程序集支持被添加到NT 5.1(Windows XP),Windows加载程序首先通过扫描带有程序集名称的文件夹来查找程序集。

因此,举例来说,如果你需要与你的应用程序分发为Visual C 2008的Microsoft Visual C运行时,你可以创建一个文件夹结构,看起来像这样:

--> Application Folder 
    --> Application.exe 
    --> MyDll1.dll 
    --> MyDll2.dll 
    --> Microsoft.VC90.CRT 
    --> Microsoft.VC90.CRT.manifest 
    --> msvcr90.dll 
    --> msvcp90.dll 
    --> msvcm90.dll 

此相同的方案会工作为您的第三方DLL。所有你需要做的就是将“假”程序集作为依赖程序集添加到应用程序的清单中(如果你的dll有清单,(并且它们访问第三方dll),那么它们的清单也必须有条目。

描述组件清单文件需要一个assemblyIdentity,和每个DLL文件节点:

<assembly manifestVersion="1.0"> 
    <assemblyIdentity type="Win32" name="Assembly Name" version="1.0.0.0" processorArchitecture="x86" /> 
    <file name="dll1.dll" /> 
    <file name="dll2.dll" /> 
</assembly> 

你的应用程序和DLL是与微软的Visual Studio 2005或以后建成,以下指示指令将使您的应用程序查找程序集中的dll:

#pragma comment(linker, "/manifestDependency:\"name='Assembly Name' processorArchitecture='*' version='1.0.0.0' type='win32' \"") 
+0

我们最终使用了这个答案 - 还有一些其他的箍环我们不得不跳过,以防有人在寻找解决方案! – Bids 2010-11-12 11:49:33

+1

编号有兴趣知道什么是过度的篮球?我试图涵盖所有相关的基地:) – 2010-11-12 17:43:33

您可以使用SetDLLDirectory函数为DLL指定路径。或者阅读关于使用application-specific paths的信息。