我该如何在Visual Studio中更改默认的构建输出目录?

13
在Visual Studio 2010至2013中,默认情况下(例如,当我创建一个新的控制台应用程序时),新解决方案将其编译后的可执行文件输出到 Solution name/Project name/bin/Debug/。 我想让它们输出到 Solution name/Debug/,并且对于所有其他构建配置(如“发布”)也是如此。
我可以通过手动进入每个项目的属性,转到 生成 选项卡,将 输出路径bin\Debug 更改为 ..\Debug 来实现这一点。 我必须针对每个项目和每个构建配置重复此操作。
经过数十个解决方案后,我有点厌倦每次手动完成这项繁琐任务。 有没有办法更改默认的输出路径?
适用于 Visual Studio 2013 的解决方案已足够。
3个回答

13

此属性在每个Visual Studio项目模板中都有定义。

例如,C#控制台应用程序模板位于

\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ProjectTemplates\CSharp\Windows\1033\ConsoleApplication\consoleapplication.csproj
csproj是一个XML文件,您可以随意编辑。生成输出目录的定义方式如下(对于每个配置):

csproj是一个XML文件,您可以自由编辑。生成输出目录的定义方式如下(对于每个配置):

...
<OutputPath>bin\Debug\</OutputPath>
...
<OutputPath>bin\Release\</OutputPath>
...

如果您更改此文件,将更改所有未来的新C#控制台应用程序项目。您还可以编写一个实用程序,列出\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ProjectTemplates中的所有csproj,并相应地更新它们。


谢谢,我想这就是我要找的东西 - 我会尝试看看它是否在今天晚些时候有效(抱歉让您等了这么久)。 - Superbest
5
您真的不应该修改全局受保护的文件。事实上,这可能会破坏服务,因为如果模板进行了修复漏洞或添加新功能的更新,您修改过的文件将不会得到更新。相反,您可以在自己的.csproj中设置<OutputPath>,它将覆盖全局设置(如果首先导入)。这是MSBuild项目内的建议。 - Heath
1
我通过创建一个新的模板,并将输出目录设置为您描述的方式来解决了我的问题,谢谢! - Superbest
在Visual Studio 12中,例如在VC/Win32下,我只看到一个相当空的.VSTDIR文件。有什么想法吗? - yO_
我简直不敢相信这被接受为答案。你不应该在安装目录下乱动全局模板。请谷歌搜索Directory.Build.props或Directory.Build.targets。你会在产品源代码目录层级上找到更优雅的解决方法。 - undefined
@videoguy - 这个回答已经是10年前的了。不要嘲讽,只需发表你自己的回答。 - undefined

3

这不是必需的。

在解决方案中,加粗显示启动项目,通常为一个EXE(例如控制台应用程序)项目。使用"项目 + 添加引用"将其他项目的引用添加到解决方案中,这样您就可以在控制台应用程序中使用那些项目生成的类库。

这些引用将具有"复制本地"属性设置为True。

构建项目时,MSBuild将自动将这些程序集从它们各自的bin\Debug目录复制到控制台应用程序的bin\Debug目录中,这要归功于"复制本地"设置。它还足够聪明,可以查看这些类库的依赖项并复制它们。

因此,在构建完成后,bin\Debug目录将不仅包含控制台模式项目的EXE文件,而且还包括其执行所需的所有DLL文件。

这种情况可能会出现一些问题,MSBuild无法确定这种依赖关系实际上存在。这种情况非常罕见,例如,您必须在代码中使用反射来加载程序集(Assembly.Load()和相关函数)。解决此问题的方法是在后构建事件中明确复制依赖项。根据您提供的信息,很难判断是否存在这个真正的问题。

您要求的内容肯定是可能实现的,只是IDE没有简化操作,因为它不设计到这种必需性。您需要将"生成+输出路径"设置为,例如,..\Debug。您可以创建自己的项目模板,并预设这个设置。创建一个新的类库项目,更改设置,使用文件+导出模板来创建该模板。在创建下一个项目时,就可以使用该模板了。

但是,请先找出默认的复制本地机制为什么无法正常工作。


将解决方案中的所有项目输出到一个文件夹中是有意义的,这样可以节省一些时间和空间(考虑固态硬盘)。因为内部解决方案依赖项只存在于一个输出文件夹中,所以复制它们会更加方便。 - Firo
1
这不是MSBuild的设计方式。你可以和构建系统斗争,但这并不是很有效率。而且,不,你没有节省时间。复制构建输出文件是一个简单的内存到内存的拷贝,在现代计算机上运行速度超过10 GB /秒。只需要半毫秒,你根本不会注意到它。万岁文件系统缓存。如果你想这样做,那么MSBuild不会阻止你,只会给你带来麻烦。 - Hans Passant
我认为我的问题陈述可能会预设这是必要的。明确一下,我现在想要这样做的原因(将来可能还有其他原因)是我喜欢将输入文件馈送到程序中并将输出生成到文件中,这意味着我经常在调试和开发时访问这些文件。我猜你会建议我将这些文件添加到我的项目中,在Visual Studio内部进行编辑,并允许它们在构建期间被复制——听起来像个好主意,尽管我需要考虑一下它是否能解决我所有的问题。 - Superbest
听起来相当可疑。确保在调试时保存使用的数据与用户保存在同一位置。谁会把它存储在与您的构建输出不同的位置呢?使用%appdata%是相当必要的。 - Hans Passant
如果您的代码使用了依赖反转,那么这个问题就不会得到解决。我正在开发一个解决方案,其主要项目不应该依赖于解决方案中的某些其他项目进行编译,而是相反,其他项目依赖于主项目。然而,在运行时,dll文件需要存在,并且会被动态加载。 - José Margaça Lopes
一个后构建事件总是可以解决这样的问题。你必须编写一个,那又怎样呢? - Hans Passant

1

不要更改全局受保护的文件,您可以创建自己的 .targets 文件来更改 <OutputPath> 以任何您想要的方式,并将其导入到您的项目中。这还可以设置其他默认值,您可能想要更改但不想为每个项目做出更改。然后,在您的项目文件中,您只需要添加类似于以下内容的东西(当然是在根元素之后):

<Import Project="$(SolutionDir)\Common.targets"/>

这并没有真正回答我认为的问题,你仍然需要进行手动操作(甚至没有使用IDE)。你能解释如何通过“默认”方式自动将该导入添加到您所有的项目中吗? - Simon Mourier

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