HintPath versus ReferencePath in Visual Studio

Wat is precies het verschil tussen het HintPathin een .csproj-bestand en het ReferencePathin een .csproj.user-bestand? We proberen ons te committeren aan een conventie waarbij afhankelijkheids-DLL’s zich in een “releases” svn-repo bevinden en alle projecten naar een bepaalde release verwijzen. Omdat verschillende ontwikkelaars verschillende mapstructuren hebben, werken relatieve verwijzingen niet, dus hebben we een schema bedacht om een ​​omgevingsvariabele te gebruiken die naar de releasemap van de betreffende ontwikkelaar verwijst om een ​​absolute referentie te creëren. Dus nadat een verwijzing is toegevoegd, bewerken we het projectbestand handmatig om de verwijzing naar een absoluut pad te wijzigen met behulp van de omgevingsvariabele.

Ik heb gemerkt dat dit kan worden gedaan met zowel het HintPathals het ReferencePath, maar het enige verschil dat ik tussen beide kon vinden, is dat HintPathwordt opgelost tijdens het bouwen en ReferencePathwanneer het project in de IDE wordt geladen. Ik weet echter niet precies wat de gevolgen daarvan zijn. Ik heb gemerkt dat VS soms de .csproj.userherschrijft en ik moet de ReferencePathherschrijven, maar ik weet niet zeker waardoor dat wordt geactiveerd.

Ik heb gehoord dat het het beste is om het bestand .csproj.userniet in te checken omdat het gebruikersspecifiek is, dus ik zou daar graag naar streven, maar ik heb ook gehoord dat de HintPath-gespecificeerde DLL is niet “gegarandeerd” om te worden geladen als dezelfde DLL bijv. bevindt zich in de uitvoermap van het project. Enige gedachten hierover?


Antwoord 1, autoriteit 100%

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

Er is een zoekvolgorde voor samenstellingen tijdens het bouwen. De zoekvolgorde is als volgt:

  • Bestanden van het huidige project – aangegeven door ${CandidateAssemblyFiles}.
  • $(ReferencePath) eigenschap die afkomstig is uit .user/targets-bestand.
  • %(HintPath) metadata aangegeven door referentie-item.
  • Doelkadermap.
  • Mappen gevonden in register dat gebruikmaakt van AssemblyFoldersEx-registratie.
  • Geregistreerde assembly-mappen, aangegeven met ${AssemblyFolders}.
  • $(OutputPath) of $(OutDir)
  • GAC

Dus, als de gewenste assembly wordt gevonden door HintPath, maar een alternatieve assembly kan worden gevonden met ReferencePath, dan zal deze de voorkeur geven aan de ReferencePath‘d montage naar de HintPath‘d een.


Antwoord 2, autoriteit 23%

Kijk in het bestand Microsoft.Common.targets

Het antwoord op de vraag staat in het bestand Microsoft.Common.targetsvoor uw doelframeworkversie.

Voor .Net Framework versie 4.0 (en 4.5 !) is het AssemblySearchPaths-element als volgt gedefinieerd:

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

Voor .Net Framework 3.5 is de definitie hetzelfde, maar de opmerking is onjuist. De 2.0-definitie is iets anders, het gebruikt $(OutputPath) in plaats van $(OutDir).

Op mijn computer heb ik de volgende versies van het bestand 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

Dit is met Visual Studio 2008, 2010 en 2013 geïnstalleerd op Windows 7.

Het feit dat de uitvoermap wordt doorzocht, kan een beetje frustrerend zijn (zoals de originele poster aangeeft) omdat het een onjuist HintPath kan verbergen. De oplossing bouwt goed op uw lokale computer, maar breekt af wanneer u verder bouwt in een schone mappenstructuur (bijvoorbeeld op de bouwmachine).


Antwoord 3, autoriteit 3%

Mijn eigen ervaring is dat je je het beste kunt houden aan een van de twee soorten montagereferenties:

  • Een ‘lokale’ assembly in de huidige build-directory
  • Een vergadering in de GAC

Ik heb ontdekt (net zoals je hebt beschreven) andere methoden die ofwel te gemakkelijk te breken zijn of vervelende onderhoudsvereisten hebben.

Elke assembly die ik niet naar GAC wil, moet in de uitvoeringsdirectory staan. Elke assembly die niet in de uitvoeringsdirectory I GAC staat of kan staan ​​(beheerd door automatische buildgebeurtenissen).

Dit heeft me tot nu toe geen problemen opgeleverd. Hoewel ik zeker weet dat er een situatie is waarin het niet zal werken, is het gebruikelijke antwoord op elk probleem “oh, gewoon GAC it!”. 8 D

Hopelijk helpt dat!


Antwoord 4

Hoewel dit een oud document is, heeft het me geholpen het probleem op te lossen dat ‘HintPath’ op een andere computer wordt genegeerd. Het was omdat de DLL waarnaar wordt verwezen ook in bronbeheer moest staan:

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

Uittreksel:

Om een ​​buitenste systeemassemblage op te nemen en er vervolgens naar te verwijzen
1. Klik in Solution Explorer met de rechtermuisknop op het project dat naar de assembly moet verwijzen en klik vervolgens op Bestaand item toevoegen.
2. Blader naar de assembly en klik op OK. De assembly wordt vervolgens gekopieerd naar de projectmap en automatisch toegevoegd aan VSS (ervan uitgaande dat het project al onder bronbeheer staat).
3. Gebruik de knop Bladeren in het dialoogvenster Referentie toevoegen om een ​​bestandsverwijzing naar assembly in de projectmap in te stellen.

Other episodes