【问题标题】:HintPath vs ReferencePath in Visual StudioVisual Studio 中的 HintPath 与 ReferencePath
【发布时间】:2010-12-25 07:40:02
【问题描述】:

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

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

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

【问题讨论】:

    标签: .net visual-studio dependencies


    【解决方案1】:

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

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

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

    因此,如果 HintPath 找到了所需的程序集,但可以使用 ReferencePath 找到替代程序集,则它将更喜欢 ReferencePath 'd 组装到 HintPath'd 一个。

    【讨论】:

    • 除了他们在 VS2019 中改变了这个 - 我们已经使用这个设置多年了。不再。存储库文件现在比解决方案构建 dll 文件具有更高的优先级 - 看图 :(
    • @Christian:什么是存储库文件?你有更多这方面的信息吗?
    • @testing 我说的是外部引用路径,你可以在VS的项目设置中设置。不幸的是,项目环境的这个 crazy important 设置(我们有三个不同的环境),无法保存到项目设置中;所以你必须明确地将它作为参数添加到命令行编译脚本。
    【解决方案2】:

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

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

    摘录:

    包含然后引用外部系统程序集 1. 在解决方案资源管理器中,右键单击需要引用程序集的项目,然后单击添加现有项。 2. 浏览到程序集,然后单击确定。然后将程序集复制到项目文件夹并自动添加到 VSS(假设项目已经在源代码管理下)。 3. 使用“添加引用”对话框中的“浏览”按钮设置项目文件夹中程序集的文件引用。

    【讨论】:

    • 请注意,在上面的步骤(2)中,可以选择“添加为链接”而不是“添加”,然后程序集只是作为链接引用而不是复制。如果在多个项目中引用相同的程序集,这将很有用。
    【解决方案3】:

    查看文件 Microsoft.Common.targets

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

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

    .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。该解决方案可以在您的本地机器上构建,但是当您在干净的文件夹结构中构建时(例如在构建机器上)会中断。

    【讨论】:

    【解决方案4】:

    我自己的经验是,最好坚持以下两种汇编参考中的一种:

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

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

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

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

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2010-10-02
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      • 2014-11-08
      • 2021-10-04
      • 1970-01-01
      • 2010-09-17
      • 2013-03-17
      相关资源
      最近更新 更多