Visual Studio'da HintPath ve ReferencePath Karşılaştırması


120

HintPathBir .csproj dosyasındaki ile ReferencePathbir .csproj.userdosyadaki arasındaki fark tam olarak nedir ? Bağımlılık DLL'lerinin bir "sürümler" svn deposunda olduğu ve tüm projelerin belirli bir sürüme işaret ettiği bir kurala uymaya çalışıyoruz. Farklı geliştiricilerin farklı klasör yapıları olduğundan, göreceli referanslar çalışmayacaktır, bu nedenle, mutlak bir referans oluşturmak için belirli geliştiricinin sürümler klasörüne işaret eden bir ortam değişkenini kullanmak için bir şema bulduk. Bu nedenle, bir referans eklendikten sonra, referansı ortam değişkenini kullanarak mutlak bir yola değiştirmek için proje dosyasını manuel olarak düzenleriz.

Bu ikisi ile yapılabilir fark ettik HintPathve ReferencePathama aralarında bulabildiğim tek fark olduğunu HintPathderleme sırasında çözümlenir ve ReferencePathproje IDE içine yüklendiğinde. Yine de bunun sonuçlarının ne olduğundan emin değilim. VS'nin bazen yeniden yazdığını .csproj.userve yeniden yazmam gerektiğini fark ettim ReferencePath, ancak bunu neyin tetiklediğinden emin değilim.

.csproj.userKullanıcıya özel olduğu için dosyayı teslim etmemenin en iyisi olduğunu duydum, bu yüzden bunu hedeflemek isterim, ancak aynı zamanda HintPath-belirtilen DLL'nin yüklenmesinin "garantili" olmadığını da duydum. aynı DLL örneğin projenin çıktı dizininde bulunur. Bununla ilgili herhangi bir fikrin var mı?

Yanıtlar:


133

Bu MSDN bloguna göre: https://blogs.msdn.microsoft.com/manishagarwal/2005/09/28/resolving-file-references-in-team-build-part-2/

İnşa ederken montajlar için bir arama sırası var. Arama sırası aşağıdaki gibidir:

  • Mevcut projedeki dosyalar - $ {CandidateAssemblyFiles} ile gösterilir.
  • .User / hedefler dosyasından gelen $ (ReferencePath) özelliği.
  • Referans öğesi tarafından belirtilen% (HintPath) meta verisi.
  • Hedef çerçeve dizini.
  • AssemblyFoldersEx Kaydını kullanan kayıt defterinde bulunan dizinler.
  • $ {AssemblyFolders} ile gösterilen kayıtlı derleme klasörleri.
  • $ (OutputPath) veya $ (OutDir)
  • GAC

Dolayısıyla, istenen derleme HintPath tarafından bulunursa , ancak alternatif bir derleme ReferencePath kullanılarak bulunabilirse , ReferencePath 'd derlemesini HintPath ' d' ye tercih edecektir .


2
Bunu VS2019'da değiştirmeleri dışında - bu kurulumu yıllardır kullanıyoruz. artık değil. Depo dosyaları artık çözüm derleme dll dosyalarından daha yüksek önceliğe sahip - go figure :(
Christian

@Christian: Depo dosyaları nedir? Bununla ilgili daha fazla bilginiz var mı?
test

@testing Harici referans yollarından bahsediyorum, VS'nin proje kurulumunda ayarlayabilirsiniz. Maalesef proje ortamı için bu çılgın önemli ayar (üç farklı ortamımız var) proje ayarlarına kaydedilemez; bu nedenle, bunu komut satırı derleme betiğine parametre olarak açıkça eklemeniz gerekir.
Christian

31

Microsoft.Common.targets dosyasına bakın

Sorunun cevabı Microsoft.Common.targets, hedef çerçeve sürümünüzün dosyasında bulunur .

.Net Framework sürüm 4.0 (ve 4.5!) İçin AssemblySearchPaths öğesi şu şekilde tanımlanır:

    <!--
    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 için tanım aynıdır, ancak yorum yanlıştır. 2.0 tanımı biraz farklıdır, $ (OutDir) yerine $ (OutputPath) kullanır.

Makinemde Microsoft.Common.targets dosyasının aşağıdaki sürümleri var:

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

Bu, Windows 7'de yüklü Visual Studio 2008, 2010 ve 2013'tür.

Çıktı dizininin aranması biraz sinir bozucu olabilir (orijinal posterin işaret ettiği gibi) çünkü yanlış bir HintPath'i gizleyebilir. Çözüm, yerel makinenizde iyi bir şekilde oluşturulur, ancak temiz bir klasör yapısı oluşturduğunuzda (örneğin, inşa makinesinde) bozulur.


Benzer bir problemim var bu durumda dll dosyalarını nereye koymalıyım? Framework veya Framework64? stackoverflow.com/questions/45945579/…
Chetan Sachdev

5

Kendi deneyimlerime göre en iyisi, iki tür montaj referansından birine bağlı kalmaktır:

  • Geçerli yapı dizininde bir 'yerel' derleme
  • GAC'de bir montaj

Çok kolay kırılabilecek veya rahatsız edici bakım gereksinimlerine sahip başka yöntemler buldum (daha önce anlattığınız gibi).

GAC'yi istemediğim herhangi bir derleme yürütme dizininde yaşamak zorunda. Yürütme dizini I GAC (otomatik derleme olayları tarafından yönetilen) içinde olmayan veya bulunamayan herhangi bir derleme.

Bu şimdiye kadar bana herhangi bir sorun çıkarmadı. İşe yaramayacağı bir durum olduğundan emin olduğum halde, herhangi bir sorunun olağan yanıtı "oh, sadece GAC it!" 8 D

Umarım yardımcı olur!


1

Bu eski bir belge olmasına rağmen, 'HintPath'in başka bir makinede göz ardı edilmesi sorununu çözmeme yardımcı oldu. Bunun nedeni, başvurulan DLL'nin de kaynak denetiminde olması gerektiğiydi:

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

Alıntı:

Bir dış sistem montajını dahil etmek ve sonra referans vermek için
1. Çözüm Gezgini'nde, montaja başvurması gereken projeye sağ tıklayın ve ardından Mevcut Öğeyi Ekle öğesine tıklayın.
2. Montaja göz atın ve ardından Tamam öğesine tıklayın. Derleme daha sonra proje klasörüne kopyalanır ve otomatik olarak VSS'ye eklenir (projenin zaten kaynak kontrolü altında olduğu varsayılarak).
3. Proje klasöründeki montaja bir dosya referansı ayarlamak için Referans Ekle iletişim kutusundaki Gözat düğmesini kullanın.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.