VS2010中各种⽂件的说明
作者:
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布局,项⽬最后编译的⽽⼜没有关掉的⽂件(下次打开时⽤)。
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 r
eason 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 之前,你使⽤(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的两个⽣成过程( 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>
我们发现原来这是⼀个XML格式的⽂件,其中<dependency>这⼀部分指明了其依赖于⼀个名字叫做Microsoft.VC80.CRT的库。但是我们发现,<assemblyIdentity>属性⾥⾯还有其它的东东,分别是
type系统类型,version版本号,processorArchitecture平台环境,publicKeyToken公匙(⼀般⽤来标⽰⼀个公司)……把他们加在⼀起便成了“强⽂件名”了,有了这种“强⽂件名”,我们就可以根据其区分
不同的版本、不同的平台……总之,有了这种强⽂件名,系统中可以有多个不同版本的相同的库共存⽽不会发⽣冲突。
[深⼊]
恩,那么现在,我们就来具体了解⼀下这⼀套机制。
⾸先是强弱⽂件名的问题。正如上⾯提到的那样,为了区分不同版本或不同⼚商⽣成的相同的程序集,必须⽤⼀个Assembly Manifest程序清单来列出我这个程序集的强⽂件名--慢着,到这⾥你可能会问:刚才不是说Assembly Manifest程序清单是列出其所依赖的程序集的强⽂件名呢,怎么这⾥变成了当前⽂件的强⽂件明了呢?其实,Assembly Manifest程序清单有两部分功能,上⾯这个实例之所以标注了其所依赖的⽂件的强⽂件名是因为其是客户端的Assembly Manifest,在服务端有另外⼀个Manifest 来标注。
mysql下载的vs库放在那个文件里<?xml version="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:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"xmlns:dsig="/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-
com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="/2000/09/xmldsig#sha1">
</dsig:DigestMethod><dsig:DigestValue>phRUExlAeZ8BwmlD8VlO5udAnRE=</dsig:DigestValue></asmv2:hash></file>
<file name="msvcp80.dll"hash="cc4ca55fb6aa6b7bb8577ab4b649ab77e42f8f91"hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"xmlns:dsig="/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-
com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="/2000/09/xmldsig#sha1">
</dsig:DigestMethod><dsig:DigestValue>7AY1JqoUvK3u/6bYWbOagGgAFbc=</dsig:DigestValue></asmv2:hash></file>
<file name="msvcm80.dll"hash="55e8e87bbde00d1d96cc119ccd94e0c02c9a2768"hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"xmlns:dsig="/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-
com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="/2000/09/xmldsig#sha1">
</dsig:DigestMethod><dsig:DigestValue>hWq8zazTsMeKVxWFBa6bnv4hEOw=</dsig:DigestValue></asmv2:hash></file>
</assembly>
这个便是从WINDOWS\WinSxS\Manifests⽬录下取出来的⼀个manifest⽂件,再这个⽂件夹下有⼀陀⼦这种XML格式的manifest⽂件,其是服务端的程序清单。WinSxs是windows XP以上版本提供的[blue]⾮托管并⾏缓存(side-by-side catche)[/blue]⾥⾯安装了各种版本的经过强⽂件名签名的系统库,⽽上⾯这个⽂件<assemblyIdentity>正是标注了系统中Microsoft.VC80.CRT的⼀个版本的强⽂件名签名,如果其和客户端。.manifest 清单⾥⾯<dependentAssembly>所列出的依赖项对上的话,就会被加载。刚才说的side-by-side 是指各种不同的版本并⾏运⾏。
上⾯这个服务端manifest⽂件中<file>标签具体指明了当前强⽂件名签名的到底是哪⼀个⽂件,其中还有这个⽂件的Hash签名,以确保⽂件的完整性。
好了,有了这⼀套机制,就可以⾮常⾮常安全地进⾏库⽂件关联了,但是、但是貌似还有⼀个⼀直困扰我们的问题:这套机制安全是安全了,但是却失去了以前良好的前后版本兼容性,即如果你的系统库发⽣了升级,那么服务端的版本号发⽣了变化,那岂不是所有服务端程序都不能使⽤了吗?其实,windows还使⽤⼀个policy的策略⽂件来确认映射关系。
<?xml version="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>
这便是在WINDOWS\WinSxS\Policies⽬录下的⼀个Policy⽂件,其中<bindingRedirect>标签便指定了所有8.0.41204.256-
8.0.50608.0变本的客户需求映射到8.0.50727.42这个我现在系统中安装的⽐较新的版本的库。当然我们也能对别的字段进⾏映射,这样便能很好解决系统升级带来的问题。
[应⽤]
经过以上的讲解,⼤家对整个依赖查过程都有了⼀个整体的认识,那么在实际中问题就好解决了。
让我们回到实际问题中,我之前说了,把⼀个程序编译连接成可执⾏程序后,在别⼈的电脑上发现不到其所依赖的库了,那么怎么办呢?聪明的你⾃然想到把其所依赖的库相应的版本拷贝到⽬标计算机上⾯,可是……当你在拼命寻那个可执⾏⽂件的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 的清单⽂件。在此⽰例中,加载程序试图在 所在的⽂件夹中查
Microsoft.VC80.CRT.manifest。如果到该清单,加载程序将从应⽤程序⽂件夹中加载 CRT DLL。如果未到 CRT DLL,加载将失败。
尝试在 本地⽂件夹中打开⽂件夹 <assemblyName>,如果存在此⽂件夹,则从中加载清单⽂件 <assemblyName>.manifest。如果到该清
单,加载程序将从 <assemblyName> ⽂件夹中加载 CRT DLL。如果未到 CRT DLL,加载将失败。
最后,我想补充的⼀点是,在你的VC++安装⽬录下⾯的“Microsoft Visual Studio 8\VC\redist”⽬录下,有着所有的提供发布的已经配备相应.manifest的库⽂件。所以你想要发布⼀个程序最简单最安全的做法(不⽤担⼼⽤户电脑是否包含你所需要的库)就是把这个⽬录下⾯的相应的库的⽂件夹和你的可执⾏⽂件放在⼀起发布。
⽐如在X86平台下如果你的可执⾏⽂件⽤到了CRT库(废话么),那么就拷贝Microsoft Visual Studio
8\VC\redist\x86\Microsoft.VC80.CRT这个⽂件夹到你的程序所在的⽬录,⼀起发布,就万事⼤吉啦!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。