Visual Studio 2015 无法生成在 Windows XP 上成功注册的 ATL Dll

Posted

技术标签:

【中文标题】Visual Studio 2015 无法生成在 Windows XP 上成功注册的 ATL Dll【英文标题】:Visual Studio 2015 cannot produce an ATL Dll that successfully registers on Windows XP 【发布时间】:2016-03-08 13:14:08 【问题描述】:

我有一个要移植到 Win 10 的旧项目。我们需要保持与 Windows XP 的兼容性,但我未能成功让转换后的项目甚至在 XP 下注册。为了了解什么是必要的(在对 Stack Overflow 和 MSDN 进行了数周的搜索之后),我尝试使用 VS 2015 从头开始​​创建一个基于 ATL 的 Dll - 但它不起作用。在继续之前,让我先弄清楚一些事情:

1) 是的,我安装了 VS 2015,并启用了对 XP 的 C++ 支持。 2) 是的,我已将平台工具集设置为 XP 3) 是的,我已经在 XP 目标上安装了 VS 2015 x86 可再发行包

如果我只是通过 ATL 项目向导并在添加任何 COM 接口之前停止,则 Dll 在 XP 上成功注册。如果我添加一个没有任何方法的接口,regsvr32 将失败并返回代码 0xc0000005。如果我向接口添加一个方法,并提供一个实现,它会继续以同样的方式失败。

如果您能提供丢失的部分,我将不胜感激。我生成最小 Dll 的过程大约需要 5 分钟,这是我的步骤(选择的设置最接近我想要移植的 Dll):

所需环境:

您需要安装 Visual Studio 2015 并启用 XP 支持的 Win 10 系统(如果在安装时未选中 XP C++ 支持选项,您将收到构建错误;它不是默认选项),并且

安装了 VS 2015 x86 可再发行组件的 Windows XP 系统(可在此处获得:https://www.microsoft.com/en-us/download/details.aspx?id=48145)

打开VS 2015,选择File/New/New Project…

• 从对话框左侧的 Installed/Templates/Visual C++/Windows 树中,选择“ATL”作为项目类型过滤器, • 从对话框中心的模板列表中选择“ATL Project”作为项目类型。 • 从对话框顶部的下拉列表中选择“.NET Framework 3.5”作为.NET Framework • 将项目命名为“DllHoopt​​y”, • 选择对话框右下角的“为解决方案创建目录”选项。 • 单击“确定”开始项目向导。

当项目向导出现时,当前项目设置应该是“动态链接库”。

• 点击“下一步”,而不是“完成”

在“应用程序设置”页面上:

• 选择“允许合并代理/存根代码”, • 取消选择“安全开发生命周期 (SDL) 检查”。 • 取消选中“支持 MFC”和“支持 COM+ 1.0”。 • 单击“完成”创建项目和解决方案。

创建项目/解决方案时:

• 选择“Release”作为配置,选择“x86”作为平台。 • 右键单击​​ DllHoopt​​y 项目,然后选择“属性”。 • 在属性对话框中,确保配置和平台分别为“Release”和“Win32” • 如果尚未选择,请转到“配置属性/常规”面板 • 将“平台工具集”更改为“Visual Studio 2015 - Windows XP (v140_xp)” • 单击确定保存更改并关闭属性面板。

如果您在此停止并构建解决方案,生成的 dll 将成功注册。

右击DllHoopt​​y项目,在弹出的菜单中选择“Add/Class...”,弹出Add Class对话框 • 从树中选择“Installed/Visual C++/ATL”,从模板列表中选择“ATL Simple Object” • 单击“添加”开始 ATL 简单对象向导。

• 在“欢迎使用 ATL 简单对象向导”页面上,为对象指定一个“简称”Hoopt​​y。这将导致填写所有其他字段。 • 点击下一步”。 • 单击“文件类型处理程序选项”页面上的“下一步”

在“选项”页面上: • 选择“Single”作为线程模型, • 选择“否”作为“聚合”选项, • 选择“自定义”作为“界面”选项。 • 取消选中“自定义”下的“自动化兼容”框。 • 应取消选中所有“支持”框。 • 点击“完成”

此时及以后,生成的任何 dll 都将无法注册,并显示消息“DllHoopt​​y.dll 中的 DllRegisterServer 失败。返回码是 0xc0000005”

打开文件“DllHoopt​​y.idl”, • 添加“HRESULT Wub();”到“接口 IHoopt​​y”,例如将其更改为:

interface IHoopty : IUnknown
    HRESULT Wub();
;

打开“Hoopt​​y.h” • 添加:

 STDMETHOD(Wub)();

公开:CHoopt​​y 类声明末尾的部分

打开“Hoopt​​y.cpp” • 添加:

STDMETHODIMP CHoopty::Wub()

    return S_OK;

构建项目(确保 Release/x86 是选定的配置和平台)

• 将“DllHoopt​​y.dll”移动到安装了 C++ 可再发行组件的 Win XP 机器上的本地硬盘驱动器(如果您像我一样使用带有 VirtualBox 的 VM,则不是共享文件夹)。

在 XP 机器上: • 调出命令提示符, • 导航到 DllHoopt​​y.dll 的位置, • 运行“regsvr32 DllHoopt​​y.dll”。

如果我的猜测是正确的,你会得到一个错误对话框:

“DllHoopt​​y.dll 中的 DllRegisterServer 失败。返回码为:0xc0000005”

我已经尝试了很多很多东西:为 WINVER 0x0501、_WIN32_WINNT 0x0501、_ATL_XP_TARGETING 以及许多我忘记的其他内容添加定义。结果没有任何改变。

【问题讨论】:

我生成一个最小 Dll 的过程大约需要 5 分钟的努力 -- 祝你找到有时间设置或具备所有这些先决条件的人。 【参考方案1】:

    静态链接 CRT - 在配置属性/C/C++/代码生成/运行时库中选择非 DLL 多线程选项,例如发布版本中的/MT

    李>

    在 Config Properties / C/C++ / Command Line / Additional Options 下的编译器选项中添加 /Zc:threadSafeInit-(注意后面的 - 是开关的一部分)。

解决方法 #2 来自https://connect.microsoft.com/VisualStudio/feedback/details/1907257 的公开案例。

Windows Server 2003 和 Windows XP 在动态加载使用线程本地存储的 DLL(通过 LoadLibrary)时存在问题,这是线程安全静态在内部使用的,以在静态本地已初始化时提供高效执行。由于这些系统不受支持,因此极不可能为这些系统创建补丁以添加此支持,就像 Vista 和更新的操作系统中存在的那样,我们不愿意惩罚支持的操作系统的性能以提供此功能旧的不支持的功能。

要解决此问题,您可以使用 /Zc:threadSafeInit- 禁用线程安全初始化代码,这将避免线程局部变量。当然,这样做初始化代码会恢复到 VS2013 模式并且不是线程安全的,所以这个选项只有在你不依赖本地静态的线程安全时才可行。

【讨论】:

谢谢!你拯救了这一天! @dvix 经过 8 小时的调查,你救了我。我爱你。太感谢了!! 2) 为我修好了。 解决方法 #1 与 Visual Studio 2012 更新 5 一起使用。接下来我将尝试使用 Visual Studio 2019。你节省了我的时间!谢谢。

以上是关于Visual Studio 2015 无法生成在 Windows XP 上成功注册的 ATL Dll的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio 2015 中损坏的假货

解决Visual Studio(2017)软件无法重新生成问题

Visual Studio 2015 编译生成支持HTTPS协议的libcurl静态库

Visual Studio 2015 for Cordova - 无法为 iOS 构建

问题解决 Visual Studio 2015 无法复制文件“D:swapfile.sys”

无法找到visual studio 2017生成工具