HintPath vs ReferencePath di Visual Studio


120

Apa sebenarnya perbedaan antara file HintPathdalam .csproj dan file ReferencePathdalam .csproj.user? Kami mencoba untuk berkomitmen pada konvensi di mana ketergantungan DLL berada dalam repo svn "rilis" dan semua proyek mengarah ke rilis tertentu. Karena pengembang yang berbeda memiliki struktur folder yang berbeda, referensi relatif tidak akan berfungsi, jadi kami membuat skema untuk menggunakan variabel lingkungan yang menunjuk ke folder rilis pengembang tertentu untuk membuat referensi absolut. Jadi setelah referensi ditambahkan, kami secara manual mengedit file proyek untuk mengubah referensi ke jalur absolut menggunakan variabel lingkungan.

Saya perhatikan bahwa ini dapat dilakukan dengan the HintPathdan the ReferencePath, tetapi satu-satunya perbedaan yang dapat saya temukan di antara keduanya adalah yang HintPathdiselesaikan pada waktu pembuatan dan ReferencePathsaat proyek dimuat ke dalam IDE. Saya tidak begitu yakin apa konsekuensi dari itu. Saya telah memperhatikan bahwa VS kadang-kadang menulis ulang .csproj.userdan saya harus menulis ulang ReferencePath, tetapi saya tidak yakin apa yang memicu itu.

Saya pernah mendengar bahwa yang terbaik adalah tidak memeriksa .csproj.userfile karena ini khusus pengguna, jadi saya ingin membidiknya, tapi saya juga mendengar bahwa HintPath-specified DLL tidak "dijamin" untuk dimuat jika DLL yang sama misalnya terletak di direktori keluaran proyek. Ada pemikiran tentang ini?

Jawaban:


133

Menurut blog MSDN ini: https://blogs.msdn.microsoft.com/manishagarwal/2005/09/28/resolving-file-references-in-team-build-part-2/

Ada perintah pencarian untuk majelis saat membangun. Urutan pencariannya adalah sebagai berikut:

  • File dari proyek saat ini - ditunjukkan oleh $ {CandidateAssemblyFiles}.
  • $ (ReferencePath) properti yang berasal dari file .user / target.
  • % (HintPath) metadata yang ditunjukkan oleh item referensi.
  • Direktori kerangka kerja target.
  • Direktori yang ditemukan di registri yang menggunakan Pendaftaran AssemblyFoldersEx.
  • Folder perakitan terdaftar, ditunjukkan dengan $ {AssemblyFolders}.
  • $ (OutputPath) atau $ (OutDir)
  • GAC

Jadi, jika diinginkan perakitan ditemukan oleh HintPath , tapi perakitan alternatif dapat ditemukan menggunakan ReferencePath , itu akan lebih memilih ReferencePath 'd perakitan ke HintPath ' d satu.


2
Kecuali mereka mengubahnya di VS2019 - kami telah menggunakan penyiapan ini selama bertahun-tahun sekarang. tidak lagi. File repositori sekarang memiliki prioritas lebih tinggi daripada solusi membangun file dll - go figure :(
Christian

@ Christian: Apa itu file repositori? Apakah Anda memiliki informasi lebih lanjut tentang ini?
pengujian

@testing Saya sedang berbicara tentang jalur referensi eksternal, Anda dapat mengatur dalam pengaturan proyek Anda VS. Sayangnya pengaturan yang sangat penting untuk lingkungan proyek ini (kami memiliki tiga lingkungan berbeda), tidak dapat disimpan ke pengaturan proyek; jadi Anda harus menambahkannya secara eksplisit sebagai parameter ke skrip kompilasi baris perintah.
Christian

31

Lihat di file Microsoft.Common.t target

Jawaban atas pertanyaan tersebut ada dalam file Microsoft.Common.targetsuntuk versi kerangka kerja target Anda.

Untuk .Net Framework versi 4.0 (dan 4.5!) Elemen AssemblySearchPaths didefinisikan seperti ini:

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

Untuk .Net Framework 3.5 definisinya sama, tapi komentarnya salah. Definisi 2.0 sedikit berbeda, ia menggunakan $ (OutputPath) bukan $ (OutDir).

Di komputer saya, saya memiliki versi file Microsoft.Common.t Target berikut:

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

Ini dengan Visual Studio 2008, 2010 dan 2013 diinstal pada Windows 7.

Fakta bahwa direktori keluaran dicari bisa sedikit membuat frustasi (seperti yang ditunjukkan oleh poster asli) karena mungkin menyembunyikan HintPath yang salah. Solusinya membangun OK di mesin lokal Anda, tetapi rusak ketika Anda membangun di dalam struktur folder yang bersih (misalnya di mesin pembuat).


Saya memiliki masalah yang sama, dalam hal ini, di mana saya harus meletakkan file dll? Framework atau Framework64? stackoverflow.com/questions/45945579/…
Chetan Sachdev

5

Pengalaman saya sendiri adalah yang terbaik adalah tetap berpegang pada salah satu dari dua jenis referensi perakitan:

  • Rakitan 'lokal' di direktori build saat ini
  • Perakitan di GAC

Saya telah menemukan (seperti yang Anda jelaskan) metode lain yang terlalu mudah rusak atau memiliki persyaratan pemeliharaan yang mengganggu.

Perakitan apa pun yang saya tidak ingin GAC, harus tinggal di direktori eksekusi. Perakitan apa pun yang tidak atau tidak bisa berada di direktori eksekusi I GAC (dikelola oleh peristiwa build otomatis).

Ini tidak memberi saya masalah apa pun sejauh ini. Meskipun saya yakin ada situasi di mana ini tidak akan berhasil, jawaban yang biasa untuk masalah apa pun adalah "oh, GAC saja!". 8 D

Semoga membantu!


1

Meskipun ini adalah dokumen lama, tetapi ini membantu saya menyelesaikan masalah 'HintPath' yang diabaikan di komputer lain. Itu karena DLL yang direferensikan perlu berada dalam kontrol sumber juga:

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

Kutipan:

Untuk memasukkan dan kemudian mereferensikan perakitan sistem luar
1. Dalam Solution Explorer, klik kanan proyek yang perlu referensi perakitan ,, dan kemudian klik Tambahkan Item yang Ada.
2. Jelajahi perakitan, lalu klik OK. Perakitan kemudian disalin ke dalam folder proyek dan secara otomatis ditambahkan ke VSS (dengan asumsi proyek sudah di bawah kendali sumber).
3. Gunakan tombol Browse di kotak dialog Add Reference untuk mengatur referensi file ke assembly di folder project.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.