Visual Studio의 HintPath 대 ReferencePath


120

정확히의 차이 무엇입니까 HintPath.csproj 파일과 ReferencePathA의 .csproj.user파일은? 우리는 종속성 DLL이 "릴리스"svn 저장소에 있고 모든 프로젝트가 특정 릴리스를 가리키는 규칙을 적용하려고합니다. 개발자마다 폴더 구조가 다르기 때문에 상대 참조가 작동하지 않으므로 특정 개발자의 릴리스 폴더를 가리키는 환경 변수를 사용하여 절대 참조를 만드는 체계를 고안했습니다. 따라서 참조가 추가 된 후 환경 변수를 사용하여 참조를 절대 경로로 변경하도록 프로젝트 파일을 수동으로 편집합니다.

이 작업은 HintPath및을 사용하여 수행 할 수 있지만 둘 다에서 ReferencePath찾을 수있는 유일한 차이점 HintPath은 빌드시와 ReferencePath프로젝트가 IDE에로드 될 때 해결 된다는 것입니다 . 그래도 그 결과가 무엇인지 잘 모르겠습니다. 나는 VS 가끔를 다시 쓰는 것으로 나타났습니다 .csproj.user그리고 나는를 다시 작성해야 ReferencePath하지만, 나는 확실히 그 트리거 무엇인지 모르겠어요.

나는 그것이 체크하는 것이 최선이 아니라고 들었습니다 .csproj.user난 그 목표로하고 싶은, 그래서 그것의 사용자 별 때문에 파일, 그러나 나는 또한 들었습니다 HintPath-specified DLL이 경우로드 할 "보장"하지 않습니다 동일한 DLL이 예를 들어 프로젝트의 출력 디렉토리에 있습니다. 이것에 대한 어떤 생각?

답변:


133

이 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를 사용하여 대체 어셈블리를 찾을 수있는 경우 HintPath 'd 어셈블리 보다 ReferencePath'd 어셈블리를 선호합니다 .


2
그들이 VS2019에서 이것을 변경 한 것을 제외하고는-우리는이 설정을 지금까지 사용하고 있습니다. 더 이상은 아닙니다. 리포지토리 파일은 이제 솔루션 빌드 dll 파일보다 우선 순위가 높습니다.-go figure :(
Christian

@Christian : 저장소 파일이란 무엇입니까? 이것에 대한 더 많은 정보가 있습니까?
테스트

@testing 외부 참조 경로에 대해 이야기하고 있으며 VS의 프로젝트 설정에서 설정할 수 있습니다. 안타깝게도 프로젝트 환경에 대한 이 엄청나게 중요한 설정 (세 가지 다른 환경이 있음)은 프로젝트 설정에 저장할 수 없습니다. 따라서 명령 줄 컴파일 스크립트에 매개 변수로 명시 적으로 추가해야합니다.
Christian

31

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 정의는 약간 다르며 $ (OutDir) 대신 $ (OutputPath)를 사용합니다.

내 컴퓨터에는 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를 숨길 수 있기 때문에 (원본 포스터가 지적했듯이) 약간 실망 스러울 수 있습니다. 솔루션은 로컬 머신에서 정상적으로 빌드되지만 깨끗한 폴더 구조 (예 : 빌드 머신)에서 빌드 할 때 중단됩니다.


비슷한 문제가 있습니다.이 경우 dll 파일을 어디에 배치해야합니까? Framework 또는 Framework64? stackoverflow.com/questions/45945579/…
Chetan Sachdev

5

내 경험으로는 두 종류의 어셈블리 참조 중 하나를 고수하는 것이 가장 좋습니다.

  • 현재 빌드 디렉터리의 '로컬'어셈블리
  • GAC의 어셈블리

나는 (당신이 설명한 것처럼) 너무 쉽게 깨지거나 성가신 유지 보수 요구 사항이있는 다른 방법을 발견했습니다.

GAC를 원하지 않는 어셈블리는 실행 디렉터리에 있어야합니다. 실행 디렉터리 I GAC (자동 빌드 이벤트에 의해 관리 됨)에 없거나있을 수없는 모든 어셈블리.

이것은 지금까지 나에게 어떤 문제도주지 않았습니다. 작동하지 않는 상황이 있다고 확신하지만 문제에 대한 일반적인 대답은 "오, 그냥 GAC입니다!"였습니다. 8 D

도움이 되었기를 바랍니다.


1

이것은 오래된 문서이지만 다른 컴퓨터에서 'HintPath'가 무시되는 문제를 해결하는 데 도움이되었습니다. 참조 된 DLL도 소스 제어에 있어야하기 때문입니다.

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

발췌 :

외부 시스템 어셈블리를 포함하고 참조하려면
1. 솔루션 탐색기에서 어셈블리를 참조해야하는 프로젝트를 마우스 오른쪽 단추로 클릭 한 다음 기존 항목 추가를 클릭합니다.
2. 어셈블리를 찾은 다음 확인을 클릭합니다. 그런 다음 어셈블리가 프로젝트 폴더에 복사되고 VSS에 자동으로 추가됩니다 (프로젝트가 이미 소스 제어를 받고 있다고 가정).
3. 참조 추가 대화 상자에서 찾아보기 버튼을 사용하여 프로젝트 폴더의 어셈블리에 대한 파일 참조를 설정합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.