转:http://blog.csdn.net/xmsheji/article/details/6783162
SDF文件和ipch文件夹:
visual studio 2010 中新建一个项目会同时建立一个ipch目录与sdf文件,即使你删掉它,再次打开工程时还是会重新建立。动辄30、50M的容量让我们心里很不爽。其实这是2010的一个新功能,与智能提示,错误提示,代码恢复、团队本地仓库等等息息相关的东西。如果大家觉得很不爽可以关掉它。Tools —— Options —— Text Editor —— C/C++ —— Advanced ——Disable Database 设置为True,默认为false。这样,你关闭visual后删掉工程目录下的ipch与sdf就不会再产生了。如果想把这些文件保存到特定的文件夹,就要设置一下Fallback Location,否则Visual Studio会用系统的临时文件夹来保存这些文件。
.sln 和 .suo都是是解决方案文件。
.sln(Visual Studio.Solution):它通过为环境提供对项目、项目项和解决方案项在磁盘上位置的引用,可将它们组织到解决方案中。
包含了较为通用的信息,包括解决方案所包含项目的列表,解决方案内任何项的位置以及解决方案的生成配置。
比如是生成Debug模式,还是Release模式,是通用CPU还是专用的等。
此文件存储在父项目目录中,他是一个或多个.proj(项目)的集合。
.suo(Solution User Opertion):解决方案用户选项记录所有将与解决方案建立关联的选项,以便在每次打开时,它都包含您所做的自定义设置。
比如VS布局,项目最后编译的而又没有关掉的文件(下次打开时用)。
.vcxproj.filters (http://blogs.msdn.com/b/vcblog/archive/2010/03/02/visual-studio-2010-c-project-upgrade-guide.aspx)
The display of the folders and files in solution explorer is controlled by .vcxproj.filters file in VS2010. If you have folders with the same name but under different scopes, for example, “Native\Include” and “Include”, the second “Include” and the files under “Include” will not show up in solution explorer after conversion. To work around the issue, you can recreate the folder in the solution explorer and add the respective files into this folder.
.idb
文件类型:Visual Studio Intermediate Debug File
扩展名为.idb的文件是一个开发文件。
文件说明:
Intermediate file created by a Visual Studio program, such as Visual C++, during the debugging process; saves the compilers state and is used for minimal program rebuilds and incremental compilations..idb
.tlog
The .tlog files are necessary in order to ensure a proper incremental build; they contain data which tells the build system which files were accessed while the build process was taking place -- that way we can very reliably tell whether any of those files changed, and if so, then what needs to be rebuilt. These files should only be going into the Intermediate Output Directory -- we should not be copying them to the final output directory (unless you set Intermediate Output Directory the same as Final Output Directory, which is not really supported).
As for ipch files, they are indeed needed even after build is complete. We use this file to optimize intellisense performance by loading these precompiled files during intellisense requests. There's no reason to rebuild these files unless precompiled options change.
.exp文件(只有DLL工程才有)
exp文件就是导出文件(export file)。在前面的讨论中,我们讨论了使用linker去创建dll(中间还有它的导出库)现在,我们假设我们生成两个dll(or just executables)。但是他们都需要调用一些对方中函数,问题出现了。当我们生成a.dll的时候我们需要b.lib;但是b.lib在对应的b.dll生成之前没有生成,而b.dll的生成又需要a.lib。正因如此,微软的解决办法是使用exp文件,或者叫导出文件。在生成两个dll之前,你使用lib.exe(library mangager tool库管理工具)来创建一个.lib和.exp,即,DLL A 的a.lib 和a.exp,现在linker使用a.lib和DLL B 自己的东西去生成b.dll和b.lib。当你回来链接DLL A的时候你就有了b.lib。这里linker需要知道a.dll中需要导出处啥。这些信息都被缓存到了a.exp文件中。linker不需要def文件或者/EXPORT选项,它仅仅是加载a.exp中的信息。a.exp就像a.dll的两个生成过程(lib.exe and linker)的联系者一样。相似的,linker不会再次生成a.lib。总的来说,这种循环调用的情况不会和在我们的程序中出现,因此,希望你不会再你的程序中用到exp文件。
.ink文件
Incremental Linking,增量编译的意思。取消增量编译可以不生成这个文件,但是对于大工程来说,会慢一些。
.manifest文件
**************************************************************************************************************************************************
恩,为了大家都能很方便的理解,我将尽量简单通俗地进行描述。
[现象]
对这个问题的研究是起源于这么一个现象:当你用VC++2005(或者其它.NET)写程序后,在自己的计算机上能毫无问题地运行,但是当把此exe文件拷贝到别人电脑上时,便不能运行了,大致的错误提示如下:应用程序配置不正确,请重新安装程序……或者是MSVCR80D.dll 没有找到什么的(我记得不是很清楚,不过大致是这样的)
[分析]
看到这样的提示,当然不会傻到重装咯。第一反应应该是什么配置有问题、或者是缺少了什么依赖的库文件;于是我就根据以前Windows缺少库文件的经验,把所有库文件(××.DLL)统统一股脑地复制到当前文件夹下来,满心欢喜以为可以运行了,以运行……@#¥@#%¥……还是挂了。
[探索]
于是开始网上搜索,我Google,我摆渡;渐渐我发现,这一切都和一个叫做***.manifest 类型的文件发生关系,那么到底什么是 .manifest 文件呢?他有什么用,以前为什么没有?
后来,经过艰苦努力,终于得知,原来这一切都是Windows 的Assembly Manifest搞的鬼。这个东东的作用就是为了解决 以前windows上的“Dll 地狱” 问题才产生的新的DLL管理解决方案。大家知道,Dll是动态加载共享库,同一个Dll可能被多个程序所使用,而所谓“Dll 地狱”就是当不通程序依赖的Dll相同,但版本不同时,由于系统不能分辨到底哪个是哪个,所以加载错了Dll版本,然后就挂了。于是盖茨就吸取了教训,搞了一个程序集清单的东东,每个程序都要有一个清单,这个清单存再和自己应用程序同名的.manifest文件中,里面列出其所需要的所有依赖,这儿所列出的依赖可不是简单地靠文件明来区分的,而是根据一种叫做“强文件名”的东西区分的,那么什么是强文件明呢?我们来看一下这个.manifest文件便知道了。
<?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> </assembly> |
<?xmlversion="1.0"encoding="UTF-8"standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1"manifestVersion="1.0"> <noInheritable></noInheritable> <assemblyIdentity type="win32"name="Microsoft.VC80.CRT"version="8.0.50727.42"processorArchitecture="x86"publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> <file name="msvcr80.dll"hash="2a0d797a8c5eac76e54e98db9682e0938c614b45"hashalg="SHA1"><asmv2:hashxmlns:asmv2="urn:schemas-microsoft-com:asm.v2"xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:TransformAlgorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>phRUExlAeZ8BwmlD8VlO5udAnRE=</dsig:DigestValue></asmv2:hash></file> <file name="msvcp80.dll"hash="cc4ca55fb6aa6b7bb8577ab4b649ab77e42f8f91"hashalg="SHA1"><asmv2:hashxmlns:asmv2="urn:schemas-microsoft-com:asm.v2"xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:TransformAlgorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>7AY1JqoUvK3u/6bYWbOagGgAFbc=</dsig:DigestValue></asmv2:hash></file> <file name="msvcm80.dll"hash="55e8e87bbde00d1d96cc119ccd94e0c02c9a2768"hashalg="SHA1"><asmv2:hashxmlns:asmv2="urn:schemas-microsoft-com:asm.v2"xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:TransformAlgorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>hWq8zazTsMeKVxWFBa6bnv4hEOw=</dsig:DigestValue></asmv2:hash></file> </assembly> |
<?xmlversion="1.0"encoding="UTF-8"standalone="yes"?> <!-- Copyright ? 1981-2001 Microsoft Corporation --> <assembly xmlns="urn:schemas-microsoft-com:asm.v1"manifestVersion="1.0"> <assemblyIdentity type="win32-policy"name="policy.8.0.Microsoft.VC80.CRT"version="8.0.50727.42"processorArchitecture="x86"publicKeyToken="1fc8b3b9a1e18e3b"/> <dependency> <dependentAssembly> <assemblyIdentity type="win32"name="Microsoft.VC80.CRT"processorArchitecture="x86"publicKeyToken="1fc8b3b9a1e18e3b"/> <bindingRedirect oldVersion="8.0.41204.256-8.0.50608.0"newVersion="8.0.50727.42"/> </dependentAssembly> </dependency> </assembly> |
[应用]
经过以上的讲解,大家对整个依赖查找过程都有了一个整体的认识,那么在实际中问题就好解决了。
让我们回到实际问题中,我之前说了,把一个程序编译连接成可执行程序后,在别人的电脑上发现找不到其所依赖的库了,那么怎么办呢?聪明的你自然想到把其所依赖的库相应的版本拷贝到目标计算机上面,可是……当你在拼命寻找那个可执行文件的assembly manifests文件的时候,却突然发现找不到了,在执行目录下面明明只有一个exe文件嘛。是不是没有生成呢?显然不会,原来是资源连接器把那个assembly manifests文件连接到了可执行文件里面了;不信,你可以用你的vc++打开一个可执行文件看看,在其资源项里面就有一个叫做RT_MANIFEST的项目。这个里面就是二进制标示的manifests文件。那么根据这里面提供的要求,将相应版本的依赖文件(一般就是CRT运行库)拷贝到系统目录Windows\WinSxS\,记住一般会是连带着一个特殊命名的目录一起拷贝到那个文件夹下,比如CRT的运行库就是WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50608.0_x-ww_b7acac55有这样一个目录,其标注了此库的版本号以及签名等信息,以防止多个版本重名时不能复制到同一WinSxS目录下。
这样就搞定了么?如果是以前,那么一切都解决了,系统会在这个目录下面找到这个运行库,可是现在单单这样可不行,系统可是要找到这个运行库的assembly manifests文件,并且对比强文件名之后才能加载,所以所以千万别忘了把相应的manifests文件拷贝到\WinSxS\Manifests目录下面。
当然,这样在目标的系统文件夹下面打动干戈,自然有些过于暴动了,还好,Windows还为我们提供了一种私有查找方式。这种方式会在前面的位置找不到合适库的时候在本地文件夹下面找。所以你只要把之前的库以及那个manifests文件一起拷贝到你的应用程序的路径下面,就可以使用啦。
根据MSDN的说明,在本地查找并加载遵循一下规则:
在应用程序本地文件夹中查找名为 <assemblyName>.manifest 的清单文件。在此示例中,加载程序试图在 appl.exe 所在的文件夹中查找 Microsoft.VC80.CRT.manifest。如果找到该清单,加载程序将从应用程序文件夹中加载 CRT DLL。如果未找到 CRT DLL,加载将失败。 尝试在 appl.exe 本地文件夹中打开文件夹 <assemblyName>,如果存在此文件夹,则从中加载清单文件 <assemblyName>.manifest。如果找到该清单,加载程序将从 <assemblyName> 文件夹中加载 CRT DLL。如果未找到 CRT DLL,加载将失败。 |