HintPath vs Visual Studio中的ReferencePath

时间:2009-12-10 16:07:04

标签: .net visual-studio dependencies

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

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

我听说最好不要检查.csproj.user文件,因为它是特定于用户的,所以我想以此为目标,但我也听说HintPath如果相同的DLL是例如,则“保证”不加载指定的DLL位于项目的输出目录中。有什么想法吗?

4 个答案:

答案 0 :(得分:115)

根据此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 '一个。

答案 1 :(得分:27)

查看文件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>

对于.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

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

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

答案 2 :(得分:5)

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

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

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

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

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

希望有所帮助!

答案 3 :(得分:0)

虽然这是一份旧文件,但它帮助我解决了HintPath&#39;在另一台机器上被忽略。这是因为引用的DLL也需要在源代码控制中:

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

摘录:

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.