.net Visual Studio 中的 HintPath 与 ReferencePath

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1882038/
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-09-03 13:39:31  来源:igfitidea点击:

HintPath vs ReferencePath in Visual Studio

.netvisual-studiodependencies

提问by toasteroven

What exactly is the difference between the HintPathin a .csproj file and the ReferencePathin a .csproj.userfile? We're trying to commit to a convention where dependency DLLs are in a "releases" svn repo and all projects point to a particular release. Since different developers have different folder structures, relative references won't work, so we came up with a scheme to use an environment variable pointing to the particular developer's releases folder to create an absolute reference. So after a reference is added, we manually edit the project file to change the reference to an absolute path using the environment variable.

到底是什么之间的区别HintPath在.csproj的文件和ReferencePath一个.csproj.user文件?我们正在尝试遵守一个约定,其中依赖项 DLL 位于“发布”svn 存储库中,并且所有项目都指向特定版本。由于不同的开发者有不同的文件夹结构,相对引用是行不通的,所以我们想出了一个方案,使用指向特定开发者的releases文件夹的环境变量来创建绝对引用。所以在添加引用后,我们手动编辑项目文件,使用环境变量将引用更改为绝对路径。

I've noticed that this can be done with both the HintPathand the ReferencePath, but the only difference I could find between them is that HintPathis resolved at build-time and ReferencePathwhen the project is loaded into the IDE. I'm not really sure what the ramifications of that are though. I have noticed that VS sometimes rewrites the .csproj.userand I have to rewrite the ReferencePath, but I'm not sure what triggers that.

我注意到这可以通过HintPath和来完成ReferencePath,但我发现它们之间的唯一区别HintPath是在构建时和ReferencePath项目加载到 IDE 时解决。不过,我不太确定这样做的后果是什么。我注意到 VS 有时会重写.csproj.user并且我必须重写ReferencePath,但我不确定是什么触发了它。

I've heard that it's best not to check in the .csproj.userfile since it's user-specific, so I'd like to aim for that, but I've also heard that the HintPath-specified DLL isn't "guaranteed" to be loaded if the same DLL is e.g. located in the project's output directory. Any thoughts on this?

我听说最好不要签入.csproj.user文件,因为它是特定于用户的,所以我想以此为目标,但我也听说HintPath-specified DLL 不能“保证”加载,如果例如,相同的 DLL 位于项目的输出目录中。对此有何想法?

回答by ajs410

According to this MSDN blog: https://blogs.msdn.microsoft.com/manishagarwal/2005/09/28/resolving-file-references-in-team-build-part-2/

根据这个 MSDN 博客:https: //blogs.msdn.microsoft.com/manishagarwal/2005/09/28/resolving-file-references-in-team-build-part-2/

There is a search order for assemblies when building. The search order is as follows:

构建时有程序集的搜索顺序。搜索顺序如下:

  • Files from the current project – indicated by ${CandidateAssemblyFiles}.
  • $(ReferencePath) property that comes from .user/targets file.
  • %(HintPath) metadata indicated by reference item.
  • Target framework directory.
  • Directories found in registry that uses AssemblyFoldersEx Registration.
  • Registered assembly folders, indicated by ${AssemblyFolders}.
  • $(OutputPath) or $(OutDir)
  • GAC
  • 来自当前项目的文件 - 由 ${CandidateAssemblyFiles} 表示。
  • $(ReferencePath) 属性来自 .user/targets 文件。
  • %(HintPath) 由引用项指示的元数据。
  • 目标框架目录。
  • 在使用 AssemblyFoldersEx 注册的注册表中找到的目录。
  • 注册的程序集文件夹,由 ${AssemblyFolders} 表示。
  • $(OutputPath) 或 $(OutDir)
  • 海关总署

So, if the desired assembly is found by HintPath, but an alternate assembly can be found using ReferencePath, it will prefer the ReferencePath'd assembly to the HintPath'd one.

因此,如果HintPath找到了所需的程序集,但可以使用ReferencePath找到替代程序集,则它会更喜欢ReferencePath的程序集而不是HintPath的程序集。

回答by Nils Lande

Look in the file Microsoft.Common.targets

查看文件 Microsoft.Common.targets

The answer to the question is in the file Microsoft.Common.targetsfor your target framework version.

问题的答案在Microsoft.Common.targets目标框架版本的文件中。

For .Net Framework version 4.0 (and 4.5 !) the AssemblySearchPaths-element is defined like this:

对于 .Net Framework 4.0 版(和 4.5 版!),AssemblySearchPaths 元素定义如下:

    <!--
    The SearchPaths property is set to find assemblies in the following order:

        (1) Files from current project - indicated by {CandidateAssemblyFiles}
        (2) $(ReferencePath) - the reference path property, which comes from the .USER file.
        (3) The hintpath from the referenced item itself, indicated by {HintPathFromItem}.
        (4) The directory of MSBuild's "target" runtime from GetFrameworkPath.
            The "target" runtime folder is the folder of the runtime that MSBuild is a part of.
        (5) Registered assembly folders, indicated by {Registry:*,*,*}
        (6) Legacy registered assembly folders, indicated by {AssemblyFolders}
        (7) Resolve to the GAC.
        (8) Treat the reference's Include as if it were a real file name.
        (9) Look in the application's output folder (like bin\debug)
    -->
<AssemblySearchPaths Condition=" '$(AssemblySearchPaths)' == ''">
  {CandidateAssemblyFiles};
  $(ReferencePath);
  {HintPathFromItem};
  {TargetFrameworkDirectory};
  {Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)};
  {AssemblyFolders};
  {GAC};
  {RawFileName};
  $(OutDir)
</AssemblySearchPaths>

For .Net Framework 3.5 the definition is the same, but the comment is wrong. The 2.0 definition is slightly different, it uses $(OutputPath) instead of $(OutDir).

对于 .Net Framework 3.5,定义是相同的,但注释是错误的。2.0 定义略有不同,它使用 $(OutputPath) 而不是 $(OutDir)。

On my machine I have the following versions of the file Microsoft.Common.targets:

在我的机器上,我有以下版本的 Microsoft.Common.targets 文件:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets
C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Microsoft.Common.targets
C:\Windows\Microsoft.NET\Framework64\v3.5\Microsoft.Common.targets
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets

This is with Visual Studio 2008, 2010 and 2013 installed on Windows 7.

这是安装在 Windows 7 上的 Visual Studio 2008、2010 和 2013。

The fact that the output directory is searched can be a bit frustrating (as the original poster points out) because it may hide an incorrect HintPath. The solution builds OK on your local machine, but breaks when you build on in a clean folder structure (e.g. on the build machine).

搜索输出目录的事实可能有点令人沮丧(正如原始海报指出的那样),因为它可能隐藏了不正确的 HintPath。该解决方案在您的本地机器上构建正常,但是当您在干净的文件夹结构中构建时(例如在构建机器上)会中断。

回答by Task

My own experience has been that it's best to stick to one of two kinds of assembly references:

我自己的经验是,最好坚持使用两种程序集引用之一:

  • A 'local' assembly in the current build directory
  • An assembly in the GAC
  • 当前构建目录中的“本地”程序集
  • GAC 中的一个程序集

I've found (much like you've described) other methods to either be too easily broken or have annoying maintenance requirements.

我发现(很像你描述的)其他方法要么太容易坏,要么有烦人的维护要求。

Any assembly I don't want to GAC, has to live in the execution directory. Any assembly that isn't or can't be in the execution directory I GAC (managed by automatic build events).

我不想 GAC 的任何程序集都必须位于执行目录中。任何不在或不能在执行目录 I GAC 中的程序集(由自动构建事件管理)。

This hasn't given me any problems so far. While I'm sure there's a situation where it won't work, the usual answer to any problem has been "oh, just GAC it!". 8 D

到目前为止,这还没有给我带来任何问题。虽然我确定在某些情况下它不起作用,但对任何问题的通常回答都是“哦,只是 GAC 吧!”。8D

Hope that helps!

希望有帮助!

回答by nkanani

Although this is an old document, but it helped me resolve the problem of 'HintPath' being ignored on another machine. It was because the referenced DLL needed to be in source control as well:

虽然这是一个旧文档,但它帮助我解决了'HintPath'在另一台机器上被忽略的问题。这是因为引用的 DLL 也需要在源代码管理中:

https://msdn.microsoft.com/en-us/library/ee817675.aspx#tdlg_ch4_includeoutersystemassemblieswithprojects

https://msdn.microsoft.com/en-us/library/ee817675.aspx#tdlg_ch4_includeoutersystemassemblieswithprojects

Excerpt:

摘抄:

To include and then reference an outer-system assembly
1. In Solution Explorer, right-click the project that needs to reference the assembly,,and then click Add Existing Item.
2. Browse to the assembly, and then click OK. The assembly is then copied into the project folder and automatically added to VSS (assuming the project is already under source control).
3. Use the Browse button in the Add Reference dialog box to set a file reference to assembly in the project folder.