我使用Visual Studio 2015社区版构建了一个应用程序。当我的一些用户尝试运行它时,他们会收到以下错误:
程序无法启动,因为您的计算机缺少api-ms-win-crt-runtime-l1-1-0.dll。尝试重新安装该程序以解决此问题。
显然,这可以通过安装Update for Universal C Runtime in Windows(KB2999226)来解决。我可以在安装脚本中检查修补程序,但我发现执行此操作的所有方法都是too slow or unreliable。
如何防止此错误发生?我可以更改我的解决方案,以便我不需要这种依赖吗?我是否可以删除我可以删除的内容?我可以将修补程序与我的应用程序一起重新分发吗?
编辑:在项目属性中,“目标平台版本”为8.1,“平台工具集”为“Visual Studio 2015(v140)”,如果这有帮助的话。
编辑2:我已经尝试将所有Universal C Runtime Library DLL复制到应用程序目录Microsoft now allows (but doesn't recommend) local mode installation of the UCRT。 C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x64
中有41个文件,api-ms-win-crt-runtime-l1-1-0.dll
中有一个文件。但是,现在运行应用程序会导致此错误:
应用程序无法正确启动(0xc0000142)。单击“确定”关闭应用程序。
我已尝试使用MSVS 2015调试应用程序但无处可去。我在Dependency Walker中打开了可执行文件,看来我遗漏了this answer, which says that Dependency Walker is old and this is a red herring.中列出的类似DLL
我尝试通过Process Monitor(procmon)运行应用程序,没有什么不寻常的。应用程序只需在WerFault.exe上调用“Process Create”,然后调用“Thread Exit。”
编辑3:我在可执行文件上启用了loader snaps,并在从cdb运行它时得到了它,如果它有帮助:
...
00c0:1200 @ 02106250 - LdrpFindOrMapDependency - RETURN: Status: 0x00000000
00c0:1200 @ 02106250 - LdrpFindOrMapDependency - ENTER: DLL name: api-ms-win-core-sysinfo-l1-2-1.dll.
00c0:1200 @ 02106250 - LdrpFindOrMapDependency - INFO: DLL name api-ms-win-core-sysinfo-l1-2-1.dll was redirected to C:\WINDOWS\SYSTEM32\kernelbase.dll by SxS.
00c0:1200 @ 02106250 - LdrpFindOrMapDll - ENTER: DLL name: C:\WINDOWS\SYSTEM32\kernelbase.dll
00c0:1200 @ 02106250 - LdrpResolveDllName - ENTER: DLL name: C:\WINDOWS\SYSTEM32\kernelbase.dll
00c0:1200 @ 02106250 - LdrpResolveDllName - RETURN: Status: 0x00000000
00c0:1200 @ 02106250 - LdrpFindOrMapDll - RETURN: Status: 0x00000000
00c0:1200 @ 02106250 - LdrpFindOrMapDependency - RETURN: Status: 0x00000000
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlSetLastWin32Error" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlLeaveCriticalSection" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlEnterCriticalSection" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlInitializeCriticalSection" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlDeleteCriticalSection" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlQueryPerformanceCounter" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "LdrResolveDelayLoadedAPI" by name
00c0:1200 @ 02106250 - LdrpMergeNodes - INFO: Merging a cycle rooted at USER32.dll.
00c0:1200 @ 02106250 - LdrpMergeNodes - INFO: Adding cyclic module GDI32.dll.
(c0.1200): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
ntdll!LdrInitShimEngineDynamic+0x330:
00007ffc`d68732e8 cc int 3
0:000>
答案 0 :(得分:6)
您应该静态链接CRT。对于消费者应用程序,有很多场景导致特定DLL丢失或其配置拙劣。我是非常流行的Windows应用程序(每天数千次安装)的安装程序技术负责人,你不会相信常见的配置错误的Windows机器。在底部我会给出一个简短的清单。
通用CRT是一个好主意,但是相对较新,它会有一段时间(可能很长一段时间),直到它被破坏,阻止客户的PC启动。这应该是门槛:如果您的客户在没有DLL X的情况下无法登录,则可以依赖它。
常见怪异状态:
答案 1 :(得分:3)
我可以检查修补程序
请注意,这是不是修补程序非常重要。这是通过Windows Update自动提供的常规更新。所以你知道这一点,这些机器没有被维护。当然,这是非常糟糕的新闻,也有问题。
api-ms-win-crt-runtime-l1-1-0.dll缺少
这是一个操作系统DLL,通常随操作系统安装一起提供,从Win7开始。这应该缩小这些机器的问题范围,他们可能会启动XP。 Vista的赔率很小。微软不再维护XP,因此看到更新缺失并非巧合。
目标平台版本"是8.1和平台工具集"是" Visual Studio 2015(v140)"
没关系,但您需要在安装程序中仔细检查这一点,并拒绝在XP上安装。仍然可以定位XP,您必须将平台工具集设置更改为" v140_xp"。不确定社区版本中是否有该选项,如果是的话,我会感到惊讶。
...中有41个文件。
只有一个计数,ucrtbase.dll。其余的是应该出现在Windows安装目录中的api-ms-win * .dll文件。它们包含在内,因此您仍然可以在XP和Vista上运行它们,您应该将它们部署到c:\ windows \ system32或c:\ windows \ syswow64,具体取决于位数。请注意,您记录了x64目录,验证用户是否具有64位版本的Windows是您必须仔细检查安装程序的另一件事。
应用程序无法正确启动(0xc0000142)。
即STATUS_DLL_INIT_FAILED,其中一个DLL的DllMain()入口点依赖于返回的FALSE。非常糟糕的新闻,不容易调试,你肯定无法在任何地方尝试用VS2015解决这个问题,因为它在你的机器上不会失败。你需要turn on loader snaps所以操作系统加载器变得很健谈。访问具有此问题的计算机当然是强制性的。
显然,这可以通过安装更新...
来解决
是的,是时候减少你的损失了。没有人可以合理地期望您的应用在他们故意不维护他们的机器或拒绝更新它时工作。在安装程序中验证ucrtbase.dll是否存在以及何时不存在然后只是停止安装并告诉他们首先更新他们的计算机。