HintPath so với ReferencePath trong Visual Studio


120

Sự khác biệt chính xác giữa HintPathtệp .csproj và tệp ReferencePathtrong .csproj.usertệp là gì? Chúng tôi đang cố gắng cam kết một quy ước trong đó các DLL phụ thuộc nằm trong repo svn "phát hành" và tất cả các dự án đều trỏ đến một bản phát hành cụ thể. Vì các nhà phát triển khác nhau có cấu trúc thư mục khác nhau, các tham chiếu tương đối sẽ không hoạt động, vì vậy chúng tôi đã đưa ra một kế hoạch sử dụng một biến môi trường trỏ đến thư mục bản phát hành của nhà phát triển cụ thể để tạo một tham chiếu tuyệt đối. Vì vậy, sau khi một tham chiếu được thêm vào, chúng tôi chỉnh sửa thủ công tệp dự án để thay đổi tham chiếu thành một đường dẫn tuyệt đối bằng cách sử dụng biến môi trường.

Tôi nhận thấy rằng điều này có thể được thực hiện với cả cái HintPathReferencePath, nhưng sự khác biệt duy nhất tôi có thể tìm thấy giữa chúng là HintPathđược giải quyết tại thời điểm xây dựng và ReferencePathkhi dự án được tải vào IDE. Tuy nhiên, tôi không thực sự chắc chắn về sự phân nhánh của điều đó. Tôi đã nhận thấy rằng VS đôi khi viết lại .csproj.uservà tôi phải viết lại ReferencePath, nhưng tôi không chắc điều gì gây ra điều đó.

Tôi đã nghe nói rằng tốt nhất là không nên kiểm tra .csproj.usertệp vì nó dành riêng cho người dùng, vì vậy tôi muốn nhắm đến điều đó, nhưng tôi cũng nghe nói rằng HintPathtệp DLL được chỉ định không "đảm bảo" được tải nếu DLL tương tự được đặt trong thư mục đầu ra của dự án. Bất kỳ suy nghĩ về điều này?

Câu trả lời:


133

Theo blog MSDN này: https://blogs.msdn.microsoft.com/manishagarwal/2005/09/28/resolving-file-references-in-team-build-part-2/

Có thứ tự tìm kiếm các cụm khi xây dựng. Thứ tự tìm kiếm như sau:

  • Các tệp từ dự án hiện tại - được chỉ ra bởi $ {CandidateAssemblyFiles}.
  • Thuộc tính $ (ReferencePath) đến từ tệp .user / target.
  • Siêu dữ liệu% (HintPath) được chỉ định bởi mục tham chiếu.
  • Thư mục khung mục tiêu.
  • Các thư mục được tìm thấy trong sổ đăng ký sử dụng Đăng ký AssemblyFoldersEx.
  • Các thư mục lắp ráp đã đăng ký, được chỉ ra bởi $ {AssemblyFolders}.
  • $ (OutputPath) hoặc $ (OutDir)
  • GAC

Vì vậy, nếu tập hợp mong muốn được tìm thấy bởi HintPath , nhưng có thể tìm thấy một tập hợp thay thế bằng ReferencePath , thì nó sẽ thích ReferencePath 'd hơn một HintPath .


2
Ngoại trừ họ đã thay đổi điều này trong VS2019 - chúng tôi đã sử dụng thiết lập này trong nhiều năm nay. không còn nữa. Các tệp kho lưu trữ hiện có mức độ ưu tiên cao hơn các tệp dll xây dựng giải pháp - go figure :(
Christian

@Christian: Các tệp kho lưu trữ là gì? Bạn có thêm thông tin về điều này?
thử nghiệm

@testing Tôi đang nói về các đường dẫn tham chiếu bên ngoài, bạn có thể đặt trong thiết lập dự án của mình về VS. Thật không may, cài đặt quan trọng điên rồ này cho môi trường dự án (chúng tôi có ba môi trường khác nhau), không thể được lưu vào cài đặt dự án; vì vậy bạn phải thêm rõ ràng nó làm tham số cho tập lệnh biên dịch dòng lệnh.
Christian

31

Tìm trong tệp Microsoft.Common.targets

Câu trả lời cho câu hỏi có trong tệp Microsoft.Common.targets cho phiên bản khung mục tiêu của bạn.

Đối với .Net Framework phiên bản 4.0 (và 4.5!), Phần tử AssemblySearchPaths được định nghĩa như sau:

    <!--
    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>

Đối với .Net Framework 3.5, định nghĩa giống nhau, nhưng nhận xét là sai. Định nghĩa 2.0 hơi khác, nó sử dụng $ (OutputPath) thay vì $ (OutDir).

Trên máy tính của tôi, tôi có các phiên bản sau của tệp 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

Đây là với Visual Studio 2008, 2010 và 2013 được cài đặt trên Windows 7.

Thực tế là thư mục đầu ra được tìm kiếm có thể hơi bực bội (như người đăng ban đầu đã chỉ ra) vì nó có thể ẩn một HintPath không chính xác. Giải pháp xây dựng được trên máy cục bộ của bạn, nhưng bị hỏng khi bạn xây dựng trên cấu trúc thư mục sạch (ví dụ: trên máy xây dựng).


Tôi gặp vấn đề tương tự, trong trường hợp này, tôi nên đặt các tệp dll ở đâu? Framework hay Framework64? stackoverflow.com/questions/45945579/…
Chetan Sachdev

5

Kinh nghiệm của riêng tôi là tốt nhất nên bám vào một trong hai loại tham chiếu lắp ráp:

  • Một hội đồng 'cục bộ' trong thư mục bản dựng hiện tại
  • Một hội đồng trong GAC

Tôi đã tìm thấy (giống như bạn đã mô tả) các phương pháp khác quá dễ bị hỏng hoặc có các yêu cầu bảo trì khó chịu.

Bất kỳ assembly nào tôi không muốn GAC, đều phải nằm trong thư mục thực thi. Bất kỳ lắp ráp nào không hoặc không thể có trong thư mục thực thi I GAC (được quản lý bởi các sự kiện xây dựng tự động).

Điều này đã không cho tôi bất kỳ vấn đề cho đến nay. Mặc dù tôi chắc chắn rằng có một tình huống mà nó sẽ không hoạt động, nhưng câu trả lời thông thường cho bất kỳ vấn đề nào là "oh, chỉ cần GAC nó!". 8 D

Hy vọng rằng sẽ giúp!


1

Mặc dù đây là một tài liệu cũ, nhưng nó đã giúp tôi giải quyết vấn đề 'HintPath' bị bỏ qua trên một máy khác. Đó là vì DLL được tham chiếu cũng cần được kiểm soát nguồn:

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

Trích:

Để bao gồm và sau đó tham chiếu một cụm hệ thống bên ngoài
1. Trong Solution Explorer, bấm chuột phải vào dự án cần tham chiếu đến assembly,, sau đó bấm Thêm mục hiện có.
2. Duyệt đến lắp ráp, sau đó bấm OK. Sau đó, lắp ráp được sao chép vào thư mục dự án và tự động được thêm vào VSS (giả sử dự án đã được kiểm soát nguồn).
3. Sử dụng nút Duyệt trong hộp thoại Thêm Tham chiếu để đặt tham chiếu tệp thành lắp ráp trong thư mục dự án.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.