2010-06-23 69 views
26

我可以在Visual Studio中将“复制本地”的默认选项设置为False吗?在大多数情况下,当我添加一个dll作为项目的依赖项时,我想将Copy Local属性设置为False。默认情况下,它是True。有没有办法改变Visual Studio的默认行为? (2008)默认情况下将“Copy Local”设置为False?

回答

32

否 - Visual Studio使用一组内部规则来确定要将Copy Local设置为的内容。

MSDN

  1. 如果引用另一个项目,称为项目到项目的引用,则该值为
  2. 如果在全局程序集缓存中找到程序集,则值为false
  3. 作为特例,mscorlib.dll参考值为false
  4. 如果程序集位于Framework SDK文件夹中,则值为false
  5. 否则,值为true
23

其实,你可以。你需要几件事情:

  1. 创建.targets文件,使copylocal(<Private>标签,要准确)false by default
  2. 导入.csproj文件中的目标。您可以在关闭</Project>标签之前将其添加到最后一行,它会看起来像<Import Project="..\Build\yourtarget.targets" />

现在,每个包含此目标的项目都默认禁用copylocal。

缺点是你需要修改每一个csproj文件,包括新的。您可以通过modifying the VS project template解决新项目问题。在博客文章中描述的Class.cs而不是Class.cs,您需要修改Class.vstemplate(在同一个zip文件中)。

用这种方法,还有一个问题 - 路径本身。如果你在新生成的csproj文件中使用硬编码的相对路径,它们可能是错误的(除非你有平坦的项目结构)。

您可以:

  • 让VS生成正确的相对路径。不知道如何做到这一点,如果这是可能的。
  • 忽略它并为每个新的csproj手动更改路径(取决于您拥有的新项目的数量,虽然不理想,这可能是可以接受的)。
  • 使用环境变量而不是相对路径。在这种情况下,每个开发人员都需要相同的变量集。

必须有更好的解决方案,但还没有找到它。

+0

这似乎是正确的答案,我已经试过了指导和链接和它的作品! – 2012-08-01 21:24:39

+0

@AnthonyMastrean:你想出了一个巧妙的方式把进口在一个新创建的csproj文件? – ya23 2012-09-05 13:27:56

+0

我们正在玩一个通用的'.csproj'文件,该文件通过使用模板导入到每个新项目中。模板系统不是很干净,我们不确定我们是否喜欢它。 – 2012-09-05 14:58:45

5

碰碰这个,因为它似乎现在有一个NuGet包正是这一点使...

https://nuget.org/packages/CopyLocalFalse

没有尝试过呢,只是希望它帮助。

+0

有了这个nuget包,没有保证。在安装脚本中有一些预定义的过滤,它会跳过一些引用,并且只在nuget包的安装时才运行,nuget包可能已经安装并且添加了一个新的引用,同样如果nuget包被恢复在其他软件包恢复之前,哪些其他软件包可能会重置其引用程序集的本地拷贝?不推荐使用此方法。更好地使用目标来覆盖本地拷贝并拥有自己的fi滤波。 – vezenkov 2015-06-30 06:43:01

3

我们不使用.targets文件(如在由ya23答案的建议),所以我们只是在文本编辑器手动编辑.csproj项目文件和<Private>元素添加到引用,就像这样:

<Reference Include="[...]"> 
    <Private>False</Private> 
    [...] 
</Reference> 

<Private>元素的值与“Copy local”属性的值匹配。例如,如果<Private>设置为False,则“本地复制”也为false。

0

关于@herzbube发布的解决方案,如果您要关闭“复制本地”以覆盖全部(或大部分)在.csproj的文件引用,你不需要单独设置<Private>False</Private>每个Reference,你可以把直接在的.csproj如下:

<ItemDefinitionGroup> 
    <Reference> 
    <Private>False</Private> 
    </Reference> 
</ItemDefinitionGroup> 

这并不影响引用的项目与<ProjectReference>,但你可以做同样的事情 - 或者代替也可以 - 第OSE:

<ItemDefinitionGroup> 
    <ProjectReference> 
    <Private>False</Private> 
    </ProjectReference> 
</ItemDefinitionGroup> 

如果你想这两个,你可以将它们合并成一个组:

<ItemDefinitionGroup> 
    <Reference> 
    <Private>False</Private> 
    </Reference> 
    <ProjectReference> 
    <Private>False</Private> 
    </ProjectReference> 
</ItemDefinitionGroup> 

确保你把这些覆盖第一实际<Reference ...><ProjectReference ...>要影响之前因为这些块只适用于那些出现在它们下面的引用。然后,如果有几件你真的想在本地复制,那么你可以单独地(即,在单个标签本身内)覆盖那些,这次使用True

对于更高级的情况下,你可以在同一个.csproj的文件切换压倒一切的价值来回多次之间。另一种先进的技术是战略性地将一些引用放置在这些块的下面,以及上面的其他引用,所以后者不会受到影响。

所有这些都会使您的.csproj中的XML更清晰易读。但是,还有更多的好消息,让阅读...


至于选择哪些项目应该被标记<Private>False</Private>这通常将取决于具体情况,但有一些基本的东西大家可以应为首发。这是一个如此基本,简单而有效的步骤,它提供如此巨大的MSBuild可靠性改进1。和构建时加速 - 与小缺点 - 这是使用默认值(即每个项目的地方),每一个大的解决方案C#输出位置应该总是做这样的调整:

在任何和每一个Visual Studio解决方案,其建立多个C#类库与任何非平凡数的<ProjectReference>相互依赖性,并且其高潮在建立一个更应用(即可执行文件):

  1. 靠近顶端的.csproj每类库,插入<ProjectReference>块如上所示。
    原因:有没有必要进行任何.DLL收集任何它引用到自己的子目录库的,因为没有可执行的是不断从该位置运行。这种猖獗的复制是无用的忙碌,可能会不必要地拖慢你的构建,可能相当戏剧性。

  2. 在另一方面,做修改的.csproj为自己的任何解决方案的应用
    原因:可执行文件需要得到他们在各自的子目录需要私人建库,但建立单独的每个应用程序应负责分别从各自的子目录收集每一个依赖,直接进入应用程序的子目录。

这工作完全是因为对.csproj的类库引用多个其他类库,但是对于一个可执行的.csproj平时从不引用另一个可执行文件。因此,对于每一个本地建库,在其bin文件夹中的唯一.DLL会本身,而每一个本地构建的应用程序将包含全套它引用本地建库。

方便的是,没有任何更改的参考库不是由您的解决方案构建的,因为它们通常使用<Reference>而不是<ProjectReference>,并且我们根本没有修改以前的标签。但请注意刚才提到的假设;如果您的某些项目违反了该规定,则可能需要进行一些调整。

可靠性改进可能与从依赖图中的多个不相交路径收集同一个库时可能发生的文件冲突有关,尤其是在并发构建中。

相关问题