HintPath vs Visual Studio中的ReferencePath

toa*_*ven 110 .net dependencies visual-studio

到底是什么之间的区别HintPath在.csproj的文件和ReferencePath一个.csproj.user文件?我们试图提交一个约定,其中依赖DLL在"发布"svn repo中,并且所有项目都指向特定版本.由于不同的开发人员具有不同的文件夹结构,因此相对引用将不起作用,因此我们提出了一种方案,使用指向特定开发人员版本文件夹的环境变量来创建绝对引用.因此,在添加引用之后,我们手动编辑项目文件以使用环境变量将引用更改为绝对路径.

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

我听说最好不要检查.csproj.user文件,因为它是特定于用户的,所以我想针对这一点,但我也听说过,HintPath如果加载了指定的DLL并不"保证"相同的DLL例如位于项目的输出目录中.有什么想法吗?

ajs*_*410 124

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

构建时有一个组件搜索顺序.搜索顺序如下:

  • 当前项目中的文件 - 由$ {CandidateAssemblyFiles}表示.
  • 来自.user/targets文件的$(ReferencePath)属性.
  • 由引用项指示的%(HintPath)元数据.
  • 目标框架目录.
  • 在注册表中找到使用AssemblyFoldersEx注册的目录.
  • 已注册的程序集文件夹,由$ {AssemblyFolders}表示.
  • $(OutputPath)或$(OutDir)
  • GAC

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

  • 除了他们在 VS2019 中改变了这一点 - 我们已经使用这个设置很多年了。不再。存储库文件现在比解决方案构建 dll 文件具有更高的优先级 - 想想看:( (2认同)

Nil*_*nde 28

查看文件Microsoft.Common.targets

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

对于.Net Framework 4.0(和4.5!),AssemblySearchPaths-element定义如下:

    <!--
    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>
Run Code Online (Sandbox Code Playgroud)

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

在我的机器上,我有以下版本的文件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
Run Code Online (Sandbox Code Playgroud)

这是在Windows 7上安装的Visual Studio 2008,2010和2013.

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


Tas*_*ask 5

我自己的经验是,最好坚持两种装配参考之一:

  • 当前构建目录中的"本地"程序集
  • GAC中的程序集

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

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

到目前为止,这没有给我任何问题.虽然我确信有一种情况不会起作用,但任何问题的通常答案都是"哦,只是GAC吧!".8 D.

希望有所帮助!