Friday, January 26, 2007

关于vc2005的找不到MSVCR80.dll的执行错误zz

关于vc2005的找不到MSVCR80.dll的执行错误

在移植某个linux下面的工具的时候,发生了release能运行debug不能运行的情况。
我发现其实这是个普遍问题,只要你发现你的程序报出了
"...failed to start because MSVCR80.dll cannot ..."之类的错误
并不是说明你真的没有MSVCR80.dll,
你可以用depends这个工具看一下,一定是它所需要的某个版本的dll没有,比如最新的retail版
你会说,明明是debug版,为什么会ref一个retail的dll呢?
如果ms让我看source code我也许可以回答这个问题……

那么怎么办呢
在你的程序某个cpp文件里面(随便那个)中加入下面的这句话
#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.VC80.CRT ' version='8.0.50608.0' processorArchitecture='X86' publicKeyToken='1fc8b3b9a1e18e3b' language='*'\"")
其实目的就是在最后的manifest里面加入对于retail的需求,
这样runtime就会自动载入这个retail版本的CRT,这个50608是最早的版本, 一般来说vc2005都是8.0.50737.42或是更晚些,呵呵。

然后编译就可以了。

下面是我找到解决方案的地方,也有其他的类似问题的相关解决。
http://blogs.msdn.com/jreddy/archive/2005/12/23/507107.aspx

其实说到底都是因为WinSxS导致的,这个side-by-side其实是回归到了有注册表之前的世界了
在.net中加入了这个特性并取得成功之后,微软开始在很多地方加入这个side-by-side特性
包括这里,
你会发现所有的crt都被做了摘要避免被修改or不恰当的覆盖,

避免你的程序被加入manifest而被迫要在安装包中加入一个非常恐怖的大的merge module的话,
可以考虑自己重新编译一次crt,
注释掉_check_manifest的调用,再用你机器重新编译你的程序,
记得要把embed manifest设为false,
发布它吧~,呵呵

转载一下原始的内容

http://blog.kalmbachnet.de/

Using the VC 2005 shared CRT/MFC (DLL) without a manifest is not supported!
If you build your app with VC2005 and you accidently have disabled the embedding of the manifest file (or deleted the separate appname.exe.manifest file), you will get an error on XP and later!

This has to do with the checking for a valid manifest of the EXE inside the CRT/MFC DLLs "DllEntry" (via a call to _check_manifest). If the OS supports manifests (or better Side-By-Side assemblies/DLLs) the CRTs´ DLL forces the check of the EXEs´ manifest. If there is no (valid) manifest, then the DLL refuses to load (returns 0) and therefor the EXE cannot be started. It might display the following error message (or similar):
R6034
An application has made an attempt to load the C runtime library incorrectly.
Please contact the application's support team for more information.

But in the following cases the manifest checking inside the CRT-DLL is not done:

Pre-fusion OS (FindActCtxSectionStringW not found in kernel32.dll)
Loaded by instrumented-mscoree.dll (mscoree.dll and pgort80.dll is already loaded)
The path returned with GetModuleFileNameW of the DLL is longer than 8000 characters
The path to the DLL, returned by GetLongPathName is longer than 8000 characters