API-MS-WIN-CRT-STDIO,win2012提示
|笔者今天帮客户做的一台WIN2012客户安装了自己的网站,但是安装后发现,客户的软件打不开。我是这么解决的:
1:我先百度搜API-MS-WIN-CRT-STDIO绿色版,在网站上下载绿色版放系统盘注册,但是发现解决不了。
2:我发现有网友说是补丁问题,我是按照这个方法解决的:
我的系统是Windows Server 2012 R2 Standard首先我是想要安装SVN客户端,然后系统让我安装Windows Server 2012 R2 安装补丁KB2999226
思路:经过网上查找资料安装补丁KB2999226之前需要安装KB2919355,安装KB2919355之前必须安装补丁KB2919442,一层一层的。
步骤:
1、下载补丁KB2919442;KB2919355;KB2999226
请百度查找相关文件上自行下载补丁,这里也有链接:
第一步补丁下载:https://support.microsoft.com/en-us/help/2919442/march-2014-servicing-stack-update-for-windows-8-1-and-windows-server-2
第二个补丁下载:https://support.microsoft.com/en-us/help/2919355/windows-rt-8-1-windows-8-1-windows-server-2012-r2-update-april-2014
第三个补丁下载:https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows
2、首先安装完成后KB2919442,立即重启生效
3、接下来安装KB2919355,立即重启生效
4、最后安装KB2999226,立即重启生效
5、最后安装圆满成功,我的SVN客户端也安装完成。
通过这个完美解决,我也分享一些网上的资料:
因为在网上看了很多解决方案,都没有很好的解决。所以记录一下这个问题的解决。
之前使用VS2013
编译出的程序,是没有这个问题的。这个问题仅仅出现在VS2015
编译的程序上。
重新安装了一个 Windows server 2008 R2
的虚拟机,然后安装了vc_redist.exe
(VC2015x64版本),运行程序是没有问题的。这个winserver2008的系统镜像是下载的微软原版的,所以这里猜测安装win server 2012的服务器安装的系统可能并不是完整的。
解决过程
通过在服务器上的C:\Windows\System32
(64位系统System32下是64位dll,SysWOW64目录下是32位dll)下搜索也没有找到相关的dll
文件。
根据网上的一些资料,解决的办法就是安装VC运行时库
和KB2999226
补丁。这个方法我尝试过了,但是没有效果。微软提供了WindowsUCRT.zip(Windows 10 通用 C 运行时 )
下载,里面包含多个操作系统下的补丁。
既然上面的方法可能无法解决,那就先看看具体的依赖情况
使用VS2015自带dumpbin查看依赖
-
dumpbin /dependents uds_services.exe
-
Microsoft (R) COFF/PE Dumper Version 14.00.24218.2
-
Copyright (C) Microsoft Corporation. All rights reserved.
-
Dump of file uds_services.exe
-
File Type: EXECUTABLE IMAGE
-
Image has the following dependencies:
-
uds_module_foundation.dll
-
KERNEL32.dll
-
MSVCP140.dll
-
WS2_32.dll
-
MSWSOCK.dll
-
VCRUNTIME140.dll
-
api-ms-win-crt-stdio-l1-1-0.dll
-
api-ms-win-crt-heap-l1-1-0.dll
-
api-ms-win-crt-convert-l1-1-0.dll
-
api-ms-win-crt-runtime-l1-1-0.dll
-
api-ms-win-crt-string-l1-1-0.dll
-
api-ms-win-crt-environment-l1-1-0.dll
-
api-ms-win-crt-math-l1-1-0.dll
-
api-ms-win-crt-locale-l1-1-0.dll
-
Summary
-
5000 .data
-
1000 .gfids
-
5000 .pdata
-
1E000 .rdata
-
1000 .reloc
-
1000 .rsrc
-
49000 .text
-
1000 .tls
在我本机上搜索api-ms-win-crt
相关的文件,发现在4处地方都有找到
-
C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86\
-
C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x64\
-
C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service\
-
C:\Program Files (x86)\Mozilla Firefox\
使用PEtools工具,可以看到Mozilla Firefox
目录下的是VS2013
编译的版本,而我的程序是VS2015
编译的64位版本,所以使用的是C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x64\
目录下的文件。
将这几处中的相关文件拷贝到程序目录之后,重新运行,还是有dll找不到的错误。
把所有api-ms-win-crt-*...dll
文件都拷贝之后,报如下错误:
因为已经没有dll找不到的问题了,所以对于这个问题就比较费解了。因为dumpbin
并没有找出所有依赖的dll
(比如上面没有找到api-ms-win-crt-utility-l1-1-0.dll,但这个是被依赖的)。
使用Dependecy Walker
工具可以看出来,__stdio_common_vfprintf
这个函数在api-ms-win-crt-stdio-l1-1-0.dll
里面。
但是无法看出api-ms-win-crt-stdio-l1-1-0.dll
依赖了那些项目。
所以考虑是不是还有dll
没有拷贝进去。发现目录下有ucrtbase.dll
这个文件,感觉这应该是所有这些dll的基础依赖。把它拷贝进去之后,便可以正常运行了。
经过试验,这个问题的原因在于没有成功安装KB2999226
补丁,有些系统这个补丁是安装不上的。只要找到ucrtbase.dll
这个文件,拷贝到程序目录下就可以了。
因为一台机器上同时按照VS2013
和VS2015
编译出的版本可能会有冲突,所以不适合把它拷贝到System32
目录(火狐就是自带了)。
可以通过设置Path
环境变量来设置加载的dll
查找位置。因为Windows
下依赖的dll查找顺序(Dynamic-Link Library Search Order)是最后一个从Path
环境变量中查找的,从而可能导致找到的并不是你想要的。
-
# 这里将dll放置在当前路径下的api-ms-win-crt目录下
-
set Path=%Path%;%cd%\api-ms-win-crt
-
# 启动程序
-
start program
补充
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686203(v=vs.85).aspx
Windows下dll默认加载路径顺序如下:
- 应用程序所在的目录
- SetDllDirectory所设置的路径,如果没有设置,就是当前工作路径(GetCurrentDirectory)
- system目录,可通过 GetSystemDirectory获取。(通常是C:\Windows\system32)
- 16位系统的目录。(16位程序使用的,通常是C:\Windows\system)
- Windows目录,可通过GetWindowsDirectory获取。(C:\Windows)
- PATH环境变量中指定的路径。(PATH环境变量中路径的搜索顺序是在前面的优先,且系统环境变量优先于用户环境变量)
可以在程序中使用SetDllDirectory
来指定DLL加载的目录,但SetDllDirectory
的每一次调用都会替换掉之前调用的结果。可以使用AddDllDirectory
来添加多个DLL加载路径。
0 Comments.