默认情况下将“复制本地”设置为False?

时间:2010-06-23 11:13:13

标签: visual-studio copy-local

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

6 个答案:

答案 0 :(得分:37)

否 - Visual Studio使用一组内部规则来确定将“本地复制到”的内容。

来自MSDN

  
      
  1. 如果引用是另一个项目,称为项目到项目引用,则值为 true
  2.   
  3. 如果在全局程序集缓存中找到程序集,则值为 false
  4.   
  5. 作为一种特殊情况,mscorlib.dll引用的值为 false
  6.   
  7. 如果在Framework SDK文件夹中找到程序集,则值为 false
  8.   
  9. 否则,值为 true
  10.   

答案 1 :(得分:27)

实际上,你可以。你需要做几件事:

  1. 创建.targets文件,该文件可生成copylocal(<Private>标记,确切地说)false by default
  2. .csproj个文件中导入目标。您可以在关闭</Project>代码之前的最后一行添加它,它看起来像<Import Project="..\Build\yourtarget.targets" />
  3. 现在,具有此目标的每个项目都默认禁用了copylocal。

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

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

    你可以:

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

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

答案 2 :(得分:7)

我们不使用.targets文件(如ya23的回答所示),因此我们只需在文本编辑器中手动编辑.csproj项目文件,并将<Private>元素添加到参考,像这样:

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

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

答案 3 :(得分:4)

碰到这个因为看起来现在有一个nuget包允许这个......

https://nuget.org/packages/CopyLocalFalse

尚未尝试过,只是希望它有所帮助。

答案 4 :(得分:4)

从msbuild v 15开始,您可以在包含源代码的根文件夹中复制名为 Directory.Build.props 的单个文件:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
  <Reference>
    <Private>False</Private>
  </Reference>
  <ProjectReference>
     <Private>False</Private>
  </ProjectReference>
</ItemDefinitionGroup>
</Project>

没什么可做的!这适用于Visual Studio 2017以及vNext Build。您可能必须关闭Visual Studio,然后再次打开解决方案以获取文件效果。

https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-and-directorybuildtargets

答案 5 :(得分:1)

关于@herzbube发布的解决方案,如果要关闭 .csproj 文件中所有(或大多数)引用的“复制本地”,则无需设置每个<Private>False</Private>单独Reference,您可以直接将以下内容放在 .csproj 中:

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

这不会影响<ProjectReference>引用的项目,但您可以做同样的事情 - 无论是相反还是同样 - 对于那些:

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

如果您想要这两个,可以将它们合并为一个组:

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

请确保在要影响的第一个实际<Reference ...><ProjectReference ...>之前放置这些覆盖,因为这些块仅适用于它们下方显示的那些引用。然后,如果有一些你 实际上想要在本地复制,你可以单独覆盖那些 back (即,在个人标签本身),这次使用True

对于更高级的案例,您可以在同一.csproj文件中多次在 True False 之间来回切换覆盖值。另一种先进技术是策略性地将一些参考文献置于这些区块之下,以及其他区域之上,因此后者不会受到影响。

所有这些都应该使.csproj中的XML更清晰,更易于阅读。但是还有更多好消息,请继续阅读...

至于选择哪些项目应该标记为<Private>False</Private>,这通常取决于具体情况,但有一些基本的每个人可以应该。这是一个基本,简单和有效的步骤,它提供了如此巨大的 MSBuild 可靠性改进 1。和构建时加速 - 并且几乎没有任何缺点 - 每个大型解决方案使用默认(即每个项目的本地) C#输出位置应该几乎总是进行此调整:

  

在任何构建多个C#类库的Visual Studio解决方案中,包含任何非平凡数量的<ProjectReference>相互依赖关系,最终构建一个应用程序(即可执行文件):

     
      
  1. 在每个 类库<。em> 的.csproj顶部附近,插入上面显示的<ProjectReference>块。
      原因:不需要任何 .dll 将它引用的任何库收集到它自己的子目录中,因为从该位置不会运行任何可执行文件。这种猖獗的复制是无用的繁忙工作,可能会不必要地减慢你的构建速度,可能非常显着。

  2.   
  3. 另一方面, 修改任何解决方案的 应用 的.csproj >。
      原因:可执行文件需要在各自的子目录中拥有所需的所有私有库,但每个应用程序的构建应该负责将每个依赖项直接从其各自的子目录单独收集到应用程序的子目录中。 。目录

  4.   

这很有效,因为类库的.csproj可能引用多个其他类库,但可执行文件的.csproj通常不会引用另一个可执行文件。因此,对于每个本地构建的库,其bin文件夹中唯一的 .dll 将是其本身,而每个本地构建的应用程序将包含它引用的全套本地构建的库。

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

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