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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3101055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 12:09:21  来源:igfitidea点击:

Set "Copy Local" to False by default?

visual-studiocopy-local

提问by dr pain

Can I set the default-option of "Copy Local" in Visual Studio to False? In most times, when I add a dll as dependency of a project, I want the Copy Local property set to False. Per default, it is True. Is there a way to change the default behaviour of Visual Studio? (2008)

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

回答by Leom Burke

No - Visual Studio uses an internal set of rules to determine what to set Copy Local to.

否 - Visual Studio 使用一组内部规则来确定将复制本地设置为什么。

From MSDN:

MSDN

  1. If the reference is another project, called a project-to-project reference, then the value is true.
  2. If the assembly is found in the global assembly cache, the value is false.
  3. As a special case, the value for the mscorlib.dll reference is false.
  4. If the assembly is found in the Framework SDK folder, then the value is false.
  5. Otherwise, the value is true.
  1. 如果引用是另一个项目,称为项目到项目引用,则值为true
  2. 如果在全局程序集缓存中找到程序集,则值为false
  3. 作为一种特殊情况,mscorlib.dll 引用的值为false
  4. 如果在 Framework SDK 文件夹中找到程序集,则值为false
  5. 否则,该值为true

回答by ya23

Actually, you can. You need a couple things:

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

  1. Create .targetsfile that makes copylocal (<Private>tag, to be precise) false by default.
  2. Import the target in .csprojfiles. You can add it in the very last line, before closing </Project>tag, it'll look like <Import Project="..\Build\yourtarget.targets" />.
  1. 创建.targets使 copylocal(<Private>准确地说是 tag)默认为 false 的文件
  2. .csproj文件中导入目标。您可以将它添加到最后一行,在关闭</Project>标签之前,它看起来像<Import Project="..\Build\yourtarget.targets" />.

Now each project with this target has copylocal disabled by default.

现在,默认情况下,具有此目标的每个项目都禁用了 copylocal。

The drawback is that you need to modify each and every csproj file, including new ones. You can work around the new project issue by modifying the VS project template. Instead of Class.csdescribed in the blog article, you need to modify Class.vstemplate(in the same zip file).

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

With that approach, there's one more problem - the path itself. If you use hardcoded relative path in newly-generated csproj files, they may be wrong (unless you have flat project structure).

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

You can:

你可以:

  • Make VS generate correct relative path. Not sure how to do that and if that's even possible.
  • Ignore it and change the path manually for each new csproj (depending on the number of new project you have, while not ideal, that may be tolerable).
  • Use the environment variable instead of relative path. In that case every developer will need the same variable set.
  • 使 VS 生成正确的相对路径。不知道如何做到这一点,如果那是可能的。
  • 忽略它并为每个新的 csproj 手动更改路径(取决于您拥有的新项目的数量,虽然不理想,但可能可以忍受)。
  • 使用环境变量而不是相对路径。在这种情况下,每个开发人员都需要相同的变量集。

There must be better solution for that, but haven't found it yet.

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

回答by herzbube

We don't use a .targets files (as suggested in the answer by ya23), so we just edit the .csprojproject file manually in a text editor and add the <Private>element to the reference, like this:

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

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

The value of the <Private>element matches the value of the "Copy local" property. For instance, if <Private>is set to False, then "Copy local" is also false..

该值<Private>元素中的“复制本地”属性的值相匹配。例如,如果<Private>设置为 False,那么“Copy local”也是假的。

回答by gReX

Starting with msbuild v 15 you can copy a single file called Directory.Build.propsin the root folder that contains your source:

从 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>

Nothing more to do! This works well with Visual Studio 2017 and also the vNext Build. May you have to close Visual Studio and than open your solution again to take the file effect.

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

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

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

回答by mabian69

Bumping this because it seems there's now a nuget package allowing exactly this...

撞这个是因为现在似乎有一个 nuget 包允许这个......

https://nuget.org/packages/CopyLocalFalse

https://nuget.org/packages/CopyLocalFalse

Haven't tried yet, just hoping it helps.

还没试过,希望有帮助。

回答by Glenn Slayden

Regarding the solution posted by @herzbube, if you want to turn off "Copy Local" for all (or most) of the references in your .csprojfile, you don't need to set <Private>False</Private>individually on each Reference, you can just put the following directly in the .csproj:

关于@herzbube 发布的解决方案,如果您想为.csproj文件中的所有(或大部分)引用关闭“本地复制” ,则无需<Private>False</Private>在每个引用上单独设置Reference,您只需输入以下内容直接在.csproj 中

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

This doesn't affect projects referenced with <ProjectReference>, but you can do the same thing--either instead or as well--for those:

这不会影响用 引用的项目<ProjectReference>,但您可以为以下项目做同样的事情——替代或同样——:

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

If you want both of these, you can merge them into a single group:

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

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

Make sure you put these overrides prior to the first actual <Reference ...>or <ProjectReference ...>you want to affect because these blocks will only apply to those references that appear below them. Then, if there are a few that you doactually want to be locally copied, you can just override those backindividually (i.e., within the individual tag itself), this time using True.

确保将这些覆盖放在第一个实际<Reference ...><ProjectReference ...>您想要影响的覆盖之前,因为这些块将仅适用于出现在它们下方的那些参考。然后,如果有几个你真正想要本地复制,你可以覆盖这些单独(即单个标签内),此时使用True

For more advanced cases you can switch the overriding value back and forth between Trueand Falsemultiple times in the same .csproj file. Another advanced technique would be to strategically place some of your references below these blocks, and others above, so the latter won't be affected.

对于更高级的情况,您可以在同一个 .csproj 文件中多次在TrueFalse之间来回切换覆盖值。另一种先进的技术是战略性地将一些引用放置在这些块下方,而其他一些则放置在上方,这样后者就不会受到影响。

All of this should make the XML in your .csproj much cleaner and easier to read. But there's even more good news, so read on...

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



As for selecting which projects should be be marked <Private>False</Private>this will usually depend on the specific situation, but there is something fundamental everyone canand shoulddofor starters. It's a step so basic, simple and effective and it delivers such huge MSBuildreliability improvements1.and build-time speedup--and with little downside--that every large solution that uses the default (i.e. local per-project) C#output locations should almost always make this adjustment:

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

In any and every Visual Studio solution which builds multiple C# class librarieswith any non-trivial number of <ProjectReference>inter-dependencies, and which culminates in building one more applications(i.e. executables):

  1. Near the top the .csproj for every class library, insert the <ProjectReference>block shown above.
    REASON: There is no need for any .dllto gather any of the libraries it references into a sub-directory of its own, since no executable is ever run from that location. Such rampant copying is useless busywork and may be unnecessarily slowing down your build, possibly quite dramatically.

  2. On the other hand, do notmodify the .csproj for any of your solution's applications.
    REASON: Executables need to have all the privately-built libraries they need in their respective sub-directories, but the build for each app alone should be responsible for individually gathering each dependency, directly from its respective sub-directory, into the app's sub-directory.

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

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

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

This works perfectly because the .csproj for a class library may reference multiple other class libraries, but the .csproj for an executable usually never references another executable. Thus, for every locally-built library, the only .dllin its binfolder will be itself, whereas every locally-built application will contain the full set of locally-built libraries it references.

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

Conveniently, nothing changes for the referenced libraries that are not built by your solution, since these usually use <Reference>instead of <ProjectReference>, and we didn't modify the former tag at all. But do note the assumption just mentioned; if it is violated by some of your projects, you may need to make some adjustments.

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

[1.] Reliability improvements could be related to file collisions that may occur when gathering the same library from multiple disjoint paths in a dependency graph, especially in concurrent builds.

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