什么是由Visual Studio创建的obj和bin文件夹,它们有什么用途?

314

我在Visual Studio 2010中创建了一个新项目,并注意到在我的项目目录下现在有两个名为objbin的新文件夹。

在构建和调试期间会创建一对类似的文件夹 - 这些文件夹是用来做什么的?

6个回答

326

obj文件夹保存着对象或中间文件,这些编译后的二进制文件尚未链接。它们实际上是碎片,将被组合生成最终的可执行文件。编译器为每个源文件生成一个对象文件,并将这些文件放置到obj文件夹中。

bin文件夹保存二进制文件,这些是应用程序或库的实际可执行代码。

这两个文件夹都进一步分为DebugRelease文件夹,这仅对应于项目的构建配置。根据执行的构建类型,这两种文件讨论以上会被放入相应的文件夹中。这使您可以轻松确定哪些可执行文件是使用调试符号构建的,哪些是启用优化并准备发布的。

请注意,在编译时,您可以更改Visual Studio输出可执行文件的位置,即在项目的“属性”中进行设置。您还可以更改构建配置的名称和选定的选项。


4
由于某种原因,我的项目的 obj 和 bin 文件夹中没有 debug 或 release 子文件夹。如果我编辑项目设置,根据当前选择的配置来构建到 debug/release 子文件夹,当我调试应用程序时会出现无法创建数据类型的错误。我的应用程序只会查找 bin 文件夹中的 dll,并且从不知道要查找 debug 或 release 文件夹。我该如何纠正这个问题? - Anil
3
@Sly,我不明白你在问什么。一个项目只能构建应用程序(EXE)或库(DLL),不能两者都有。因此,如果你的项目创建了一个应用程序,它就不会将任何DLL放入你的bin文件夹中。而如果你的项目构建了一个库,当你尝试调试它时会出错,因为你不能执行DLL。无论如何,这似乎是因为你已经在项目属性中更改了默认输出路径。如果你需要更多帮助,请提一个新问题。一定要详细描述问题,包括你的项目配置截图(如果需要的话)。 - Cody Gray
2
我想知道是否可以强制Visual Studio在构建完成后删除obj文件夹? - Johnny_D
2
@SlyRaskal 如果你正在开发一个Web项目,可能没有Debug/Release文件夹的原因之一是什么? - Tim Iles
3
“obj”是否真的仅包含未链接的目标代码文件?根据我的经验,它包含了所有这些文件,在最后构建步骤中,“最终集合”中的文件会被复制到“bin”中。 - ivan_pozdeev
显示剩余10条评论

92
我建议您观看这个YouTube视频,它展示了C# bin和obj文件夹之间的区别,并解释了我们如何获得增量/条件编译的好处。
C#编译是一个两步骤的过程,更多细节请参见下面的图表:
1. 编译:在编译阶段,单个C#代码文件被编译成单个编译单元。这些单独的编译代码文件放在OBJ目录中。
2. 链接:在链接阶段,将这些单独的编译代码文件链接起来创建单个单位的DLL和EXE。这些文件放在BIN目录中。

C# bin vs obj folders

如果你比较"bin"和"obj"目录,你会发现"obj"目录中的文件数更多,因为它包含了单独编译的代码文件,而"bin"只有一个单元。

bin vs obj


1
我尝试使用VS 2017和.NET 4.7编译C#控制台应用程序和WPF应用程序。在两种情况下,我都找不到“单独编译的单元”,即与源文件具有1对1关系的对象。只有xaml文件似乎会为每个源文件生成中间文件。也许在较新版本的.NET中有所改变?也许我漏掉了什么?也许这就是C++的工作方式,没有人实际检查这些文件并发现它不起作用的方式? - AgostinoX

28

obj目录用于存放编译器或构建系统在构建过程中生成的中间对象文件和其他临时数据文件。而bin目录则是最终输出二进制文件(以及任何依赖项或其他可部署文件)的目录。

如果需要,您可以在项目设置中更改用于这两个目的的实际目录。


1
“bin” 可以在项目属性 -> “生成” -> “输出” -> “输出路径” 中更改。那么“obj”呢? - Peter Mortensen

8

关于obj目录的一个有趣事实:如果您在Web项目中设置了发布,将要发布的文件将被暂存到obj\Release\Package\PackageTmp目录下。如果您想自己发布文件而不使用集成的VS功能,您可以在这里获取您实际需要部署的文件,而不必在bin目录中挑选所有的数字垃圾。


6
如果你正在使用Visual Studio的安装程序项目,那么请小心。因为Visual Studio的安装程序项目中,“主要输出”是从“obj”文件夹而不是“bin”文件夹获取的。在我发现我在对“bin”文件夹的程序集执行后期构建过程时,应该针对“obj”文件夹的程序集时,我已经发布了我认为已混淆并签名的应用程序一段时间了,但实际上部署的应用程序文件既没有被混淆也没有被签名。总的来说,这远非直观,但通常的“设置”方法是使用项目的“主要输出”,而这就是“obj”文件夹。顺便说一下,如果有人能解释一下这个问题,我会很感激。

0

从更高的层面来理解这个问题会更好:编译链接,这不仅适用于c#语言,还适用于许多其他语言。

编译 - 修改后的源代码被编译成二进制目标代码。这段代码还不能执行。

链接 - 将目标代码与所需的支持代码组合起来,生成可执行程序。这一步通常涉及添加任何所需的库。

具体来说,对于.net案例,obj(对象)文件夹包含编译阶段的输出。而bin(二进制)文件夹包含链接器的输出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接