动态链接库msvcrt.dll中找不到_except_handler4_common过程入口点

5
我使用“Microsoft Visual Studio”来制作“MFC应用程序”。
我使用“Installshield”来创建该应用的安装文件。
我得到了一个“setup.exe”文件。
如果我在Windows XP 32位机器上运行此安装程序,则安装将成功结束。
但是,当我尝试启动安装的程序时,会收到以下消息:
"The procedure entry point _except_handler4_common could not be located in the dynamic link library msvcrt.dll."

在调试模式下,我无法找到错误发生的时刻,因为无论我在代码中放置多少断点,消息都会在达到断点之前出现,我猜测是在程序执行的最开始...

注意:它适用于Vista 32位和Seven 64位。

看起来很多人都有同样的问题,但我自己找不到解决方法。

你能帮忙吗? 谢谢。


Msvcrt.dll曾经被VC++项目使用了15年。除非在虚拟机中运行它们,否则您将无法再使用它们。您需要重建这些项目。 - Hans Passant
他最好通过重构和重建来解决问题,不过那个包含导出函数的DLL文件可以在Windows 8的标准安装中找到。有关更多细节,请查看我下面的答案。 - Christopher Painter
9个回答

4
欢迎来到DLL地狱和应用程序依赖性分析的世界。
我在我的Win8机器上发现了这个DLL,它位于SYSWOW64(32位System32文件夹),版本为7.0.9200.16384。使用Dependency Walker查看它,我可以看到它实际上导出了你正在寻找的函数。
我还在我的InstallShield机器上看到一个合并模块叫做MSVCRT.MSM,它重新分发了版本为6.00.8797.0的此文件。然而,当我使用Dependency Walker查看它时,我看到它具有导出函数_except_handler2和_except_handler_3,但没有_except_handler_4_common。
因此,您需要一个更新的DLL,而该合并模块将无法帮助您。微软曾经有一个很酷的网站叫做DLL Help Database,告诉您文件的所有版本以及它们的发货情况,但可悲的是,他们杀死了它。
顺便说一下,我还可以看到这个DLL现在已经安装在Windows上了。 Windows XP?我不太确定,因为我必须启动虚拟机并查看。
几个可能的解决方案:
  1. 查找修复此问题的Windows SP或Hotfix,并将其设置为MSI的依赖项。

  2. 从Win 8机器中获取DLL,将其添加到INSTALLDIR并进行私有部署。

最后需要注意的是,这可能是由于Windows XP版本使用了旧版本的DLL(相关的KB文章称确实如此),或者第三方应用程序破坏了DLL而导致的问题。这里需要进行更多的研究。


你是什么意思? 我们的一些客户和潜在客户仍然使用Win XP 32位机器。 我们需要应用程序也能在XP 32位上运行... - Léa Massiot
我已经尝试了几个dll,包括来自Vista的dll,但没有成功。我能从我的Microsoft账户下载特定的dll吗?你的dll只适用于64位机器,对吗? - Léa Massiot
这个功能是在Windows Vista中引入的。由于msvcrt.dll自Windows XP以来一直是操作系统组件,无论安装还是重新安装C/C++运行时都无法解决这个问题。这在msvcrt.dll是已知的DLL的系统上尤其如此。我没有去检查任何旧的XP虚拟机来确定它是否是已知的DLL;但如果是的话,只要该DLL以其基本名称msvcrt.dll导出,它将始终优先于搜索路径中的任何其他DLL。 - undefined
1
@0xC0000022L 你应该在你的个人资料中添加问答巫师。 :) - undefined
@ChristopherPainter 呵呵,我觉得从技术上讲,甚至有一个徽章……我会考虑的,不过 ;) - undefined
显示剩余3条评论

1

我刚刚安装了最新的VS 2017,遇到了同样的问题。我搜索了所有的内容,但是找不到任何解决方案,所以我自己定义了它:

extern "C" int _except_handler4_common() {
    return 0; // whatever, I don't know what this is
}

这是一个有创意的解决方案,但仍然不是正确的解决方案,因为这个功能比你的解决方案所展示的更为复杂 ;) - undefined
1
哈哈,我挺确定的,但是没人有时间搞这些 ;) 我的意思是,如果这是一个开源解决方案,我们可以深入了解细节,但是VS 2017...不是。 - undefined

0
这篇文章已经有些旧了,但我想留下我的解决方案,因为这个问题对我来说是个噩梦。我的Python应用程序在Linux、Win7、8和10上运行正常,但WinXP却拒绝使用该消息。
我使用py2exe获得可执行文件,它会将一些DLL文件与exe文件放在一起。
从exe目录中删除一些dll文件是唯一让应用程序在XP中工作并继续在其他系统中工作的方法:
["POWRPROF.dll","IPHLPAPI.DLL","USP10.DLL","DNSAPI.DLL"]
还要将“Microsoft.VC90.CRT”目录与exe文件一起分发,带有其清单和DLL文件。
我希望这对某人有用,因为我花了几周时间才弄明白它。
(我知道OP没有使用Python,但错误是一样的)

可以说,如果安装了VC90运行库有所帮助,那么你的错误信息根本不是关于msvcrt.dll,而是关于msvcr90.dll或类似的问题。 - undefined

0
我建议您先尝试安装MSVC Redist 2008版本。该版本包含了缺失函数的实现。

但是它在名为msvcrt.dll的DLL中并不包含该功能。而且,猜猜看,这就是错误所在。安装任意其他提供相同名称函数的DLL并不能解决任何问题。 - undefined

0

你的程序在Windows XP上存在未满足的依赖项。你可以尝试使用Dependency Walker来识别它,或者你可以检查已知的限制。例如,Visual Studio 2012直到更新1和构建选项更改才支持Windows XP - 这是你正在使用的吗?


非常感谢您的回答。在这种情况下,我的同事仍在使用MSVisual 2005。 - Léa Massiot
不需要弄明白什么。错误信息准确无误,包含了函数名未找到以及未找到的DLL名称。 - undefined

0
在Windows XP发布周期中(我记不清确切的补丁级别,可能是SP1),msvcrt.dll被设为系统DLL。您可以检查其版本信息来证明这一点。
Description:    Windows NT CRT DLL
Product:        Microsoft« Windows« Operating System

这使它成为操作系统的一个组件。然而,作为操作系统组件并不意味着它提供了您所期望的兼容性保证。与旧版本(包括VC6)的msvcrt.dll链接的程序应该是兼容的,但与更新版本链接的程序可能无法在具有旧版本msvcrt.dll的较旧操作系统上运行。该DLL已经发展,Vista引入了在这个问题中找不到的函数。
然而,作为操作系统组件,XP和7 SP1之间的WDK(DDK)包含了构建用户模式项目(DLL或程序)时链接到msvcrt.dll所需的一切。唯一的问题是:如果开发人员的目标是(或曾经是)Windows Vista及更高版本,最终的.exe或.dll文件将不可避免地包含对_except_handler4_common的引用。这将导致您问题中的确切错误消息:
“在动态链接库msvcrt.dll中找不到过程入口点_except_handler4_common。”

本质上:当你手头有一个最终产品时,你无法做任何事情。该功能是从导入表引用的,这是一个硬编码的引用,与特定的DLL名称相关联。如果你是开发者,你需要针对相应的旧版本DLL(以及相应的操作系统)进行开发。

如果你对技术细节感兴趣,请参考这里我相当详细的回答

关于其他建议解决方案的备注:

安装任何Microsoft C/C++运行时版本 - 再次强调,这个msvcrt.dll现在是一个操作系统组件,使用VC6构建的程序可能会在新的DLL版本上工作,但是针对最新DLL版本链接的新程序可能根本无法与旧的DLL版本一起工作。
从.exe所在的目录中删除msvcrt.dll可能有助于在尚未知道msvcrt.dll的系统上。例如,在Windows 10上,它是一个已知的DLL。这意味着如果导入为msvcrt.dll - 即没有完整路径 - 已知的DLL将始终优先使用。
PS:如果您使用的是较新的WDK(从Windows 8开始),您可能会链接到较新的msvcr1xx.dll而不是msvcrt.dll。这是很自然的,因为与XP和7 SP1之间的WDK不同,WDK不再包含工具链(编译器、链接器),而是期望使用Visual C++安装中的工具链。这就决定了在这种情况下与C/C++运行时的兼容性。 PPS:其他提到这一点的文章包括thisthis。请注意,WDK还包含了类似msvcrt_win2000.obj的目标文件,以提供此符号(和其他符号),因为在链接过程中,目标文件优先于.lib文件。

-1
问题可能是因为您在Win XP上使用了一个损坏的DirectX版本。我也遇到过这种情况,因为我随意下载了一个损坏的DirectX安装程序,导致出现了这些问题。我的解决方法是从C:Windows/System32中删除所有与DirectX有关的文件,同时从添加/删除程序中删除DirectX,并从regedit中完全删除整个注册表键。Local_machine/software/microsoft/DirectX...然后,我在网上找到了DirectX 9的原始值和键,并创建了一个新的注册表键。
DirectX文件夹一旦完全恢复并最初显示在regedit中,就会在dxdiag中显示DirectX已安装。
如果游戏出现崩溃,建议下载.NET Framework 3.5 Service Pack 1并在电脑上备份(如果您不使用像我一样的nVIDIA图形卡,我使用ATI Radeon),然后下载nVIDIA PhysX系统软件驱动程序并查看是否有效。 (仅在使用Win XP时需要nVIDIA phydX驱动程序才能无崩溃运行此游戏,Win 7上不应遇到此问题)。 如果驱动程序损坏了您的PC(nVIDIA PhysX驱动程序),则可以在这些驱动程序之前恢复旧的PC功能(如果您备份了PC,建议使用Acronis Boot进行备份),如果您无法在例如Windows XP上获取nVIDIA PhysX,则意味着您完全没有运气,因为没有nvidia physx,在Win XP上Metro将无法运行,而在Win 7 / Vista / 8上则可以。

我没有注意到这不是关于地铁的问题,所以请忽略答案中的最后几行,那是关于《地铁2033》的。但是如果你想玩这个游戏,答案中其余的几行将有助于帮助你顺利运行游戏。 - PrototypeUK

-2
我花了最近8个小时来检查我的代码,发现这个错误是由于我的应用程序中的一行代码引起的,具体来说是操作系统中IPv6支持的检查。
conf.IPv6Disabled = !(Socket.OSSupportsIPv6);

我将那行代码注释掉,然后问题就解决了。

这是应该作为答案吗?OP需要评论与您完全相同的行吗?我们怎么知道conf和Socket指的是什么?这是无意义的。 - Kira
是的,这应该是一个答案——在Windows XP中检查套接字是否支持IPv6的调用会抛出这个确切的错误。"Socket.OSSupportsIPv6"是.NET框架中的布尔值。 - Sean

-2
这个问题存在于每一个需要在Windows XP上运行的软件或游戏,但是它们实际上是为Windows 7、8或Vista设计的。因此,如果你想要继续或启动程序,你需要根据程序的系统要求升级到Windows 7、8或Vista。 希望这对你有所帮助。 谢谢。

我在Windows 7下编译的软件可以在Windows XP上正常运行。如果我可以为升级建议打-2分,我会这样做:在大多数情况下(除了家庭混乱),这不是一个选项。虚拟机可能是更好的建议。 - Zac
@Zac 这个说法确实是完全正确的。是的,你可以在更新的Windows版本上构建软件,以针对较旧的Windows版本。然而,开发人员需要对此进行处理。如果开发人员粗心大意,就会出现询问者感到困惑的症状。但我能理解你对升级建议感到恼火。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接