HintPath vs ReferencePath в Visual Studio

В чем разница между HintPath в файле .csproj и ReferencePath в файле .csproj.user? Мы пытаемся зафиксировать соглашение, в котором библиотеки зависимостей находятся в "релизах" svn repo, и все проекты указывают на конкретный выпуск. Поскольку разные разработчики имеют разные структуры папок, относительные ссылки не будут работать, поэтому мы придумали схему использования переменной среды, указывающей на конкретную папку релизов разработчиков, чтобы создать абсолютную ссылку. Поэтому после добавления ссылки мы вручную редактируем файл проекта, чтобы изменить ссылку на абсолютный путь, используя переменную среды.

Я заметил, что это можно сделать как с HintPath, так и с ReferencePath, но единственная разница между ними заключается в том, что HintPath разрешается во время сборки и ReferencePath, когда проект загружается в среду IDE. Я не совсем уверен, каковы последствия этого. Я заметил, что VS иногда перезаписывает .csproj.user, и мне нужно переписать ReferencePath, но я не уверен, что это заставляет.

Я слышал, что лучше не проверять файл .csproj.user, так как он зависит от пользователя, поэтому я хотел бы на это нацелиться, но я также слышал, что DLL HintPath -specified "t" гарантированно "загружается", если одна и та же DLL расположенный в каталоге вывода проекта. Любые мысли об этом?

Ответ 1

Согласно этому блогу MSDN: https://blogs.msdn.microsoft.com/manishagarwal/2005/09/28/resolving-file-references-in-team-build-part-2/

При сборке создается порядок поиска сборок. Порядок поиска выглядит следующим образом:

  • Файлы из текущего проекта - обозначены ${CandidateAssemblyFiles}.
  • $(ReferencePath), которое происходит из файла .user/target.
  • % (HintPath) метаданные, указанные ссылочным позицией.
  • Каталог целевой структуры.
  • Каталоги, найденные в реестре, которые используют регистрацию AssemblyFoldersEx.
  • Зарегистрированные папки сборки, обозначенные ${AssemblyFolders}.
  • $(OutputPath) или $(OutDir)
  • GAC

Итак, если желаемая сборка найдена HintPath, но альтернативная сборка может быть найдена с использованием ReferencePath, она предпочтет сборку ReferencePath'd для HintPath'd.

Ответ 2

Посмотрите в файле 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 "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 Include as if it were a real file name.
        (9) Look in the application 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

Это с Visual Studio 2008, 2010 и 2013, установленными в Windows 7.

Тот факт, что поиск в каталоге вывода может быть немного разочаровывающим (как указывает оригинальный плакат), поскольку он может скрыть неправильный HintPath. Решение построено на вашей локальной машине ОК, но ломается, когда вы строите в чистой структуре папок (например, на машине сборки).

Ответ 3

Мой собственный опыт состоял в том, что лучше всего придерживаться одного из двух типов ссылок на сборку:

  • "локальная" сборка в текущем каталоге сборки
  • Сборка в GAC

Я нашел (так же, как вы описали), что другие методы слишком легко сломаны или имеют раздражающие требования к обслуживанию.

Любая сборка, которую я не хочу использовать GAC, должна находиться в каталоге выполнения. Любая сборка, которая не является или не может быть в исполняющем каталоге я GAC (управляется событиями автоматической сборки).

Это пока не дает мне никаких проблем. Хотя я уверен, что там ситуация, когда это не сработает, обычный ответ на любую проблему был "о, просто GAC это!". 8 D

Надеюсь, что это поможет!

Ответ 4

Хотя это старый документ, но он помог мне решить проблему "HintPath", игнорируемую на другой машине. Это связано с тем, что ссылка на 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.