使用Microsoft.VC90.CRT摆脱DLL地狱?

使用Microsoft.VC90.CRT摆脱DLL地狱?,dll,com,assemblies,py2exe,winsxs,Dll,Com,Assemblies,Py2exe,Winsxs,我已经构建了一个inproc com服务器dll,我可以通过构建实用程序py2exe将其打包为一个或多个文件。当我允许所有依赖项保持在外部时,我没有问题,但是捆绑为一个文件会产生问题 当使用dll时(注册它或从中实例化com对象),它会立即从路径c:\windows\winsxs\x86\u microsoft.vc90.crt\u 1fc8b3b9a1e18e3b\u 9.0.30729.6871\u none\u 50944e7cb706e5\MSVCR90.dll加载,无论我做什么,我都无

我已经构建了一个inproc com服务器dll,我可以通过构建实用程序py2exe将其打包为一个或多个文件。当我允许所有依赖项保持在外部时,我没有问题,但是捆绑为一个文件会产生问题

当使用dll时(注册它或从中实例化com对象),它会立即从路径
c:\windows\winsxs\x86\u microsoft.vc90.crt\u 1fc8b3b9a1e18e3b\u 9.0.30729.6871\u none\u 50944e7cb706e5\MSVCR90.dll加载
,无论我做什么,我都无法更改它。我找不到任何信息(使用Dependency Walker)来指示是什么导致了加载。它只是奇迹般地发生

随后,它通过显式调用
LoadLibraryA(“MSVCR90.dll”)
(某些py2exe黑盒的一部分?)再次加载该dll,但这次它不会查看
winsxs
清单/目录。相反,它会查看系统路径和/或遵守dll重定向。这就是问题发生的时候。如果我将系统路径设置为以
c:\windows\winsxs\x86\u microsoft.vc90.crt…\
开始,它将加载完全相同的dll并感到高兴-但是如果使用了任何其他文件-包括完全相同的dll的副本-但路径不同-那么整个事情就完了。它无法处理使用两个不同的文件

我怎样才能解决这个问题?理想情况下,我喜欢让dll的初始魔法加载利用私有程序集,但无论我如何处理清单或.dll.local等,在第二次加载dll之前,它都不会尊重这一点

请注意,对于非绑定dll(外部依赖项),它始终使用winsxs MSVCR90.dll


我可以通过强制系统路径加载winsxs副本来“修复”使用dll的失败,但这对于可部署com服务器来说是非常无用的

原因是DLL有一个清单,告诉模块加载程序也在SxS存储中搜索

你有几个选择

  • 使用静态链接构建DLL。不使用任何MFC DLL(请参见项目设置)
  • 不要为DLL使用并排清单,而仍然使用MFC DLL。但请注意,您必须在本地路径中随DLL一起发送这些DLL(请参阅DLL搜索序列文档)
  • 使用更高版本的VS。更高版本的VS不再使用SxS存储,并且不再有用于这些DLL的清单 对于2。请参阅中的这篇文章。这里有VS-2008的更新。


    构建您的DLL

    谢谢,但我认为这一切的前提是基于我在Visual Studio中编写VC++的假设。我不是。我用Python编写了代码,并使用py2exe magic创建了dll。我可以选择静态链接或动态链接等,而不是尝试分离和重新编译底层工具。也就是说,清单中具体告诉加载程序如何使用SxS?为了让他工作,我已经调整了清单100次(尽管我不确定它是否确实受到尊重…)。我很幸运地使用了一个.dll.local来重定向,但正如在原始问题中所写的那样,只有在一些神秘的进程最初加载了dll之后,才在随后调用LoadLibrary时才会考虑这个问题。要回答我关于SxS的问题,这是publicKeyToken的工作。理论上,将其从清单中删除会指导使用私有程序集。我已经试过了,但我又试了一次。这对我没有影响。我可以加载私有程序集,但只能在“第二次”加载dll时加载。第一个仍然是SxS。我认为它包含在pythoncom和/或py2exe dll加载程序代码和嵌入式dll中。我猜解决方案需要深入研究这个来源。。。(我已经开始了,但没有成功)