HintPath กับ ReferencePath ใน Visual Studio


120

อะไรคือความแตกต่างระหว่างHintPathไฟล์. csproj และไฟล์ReferencePathใน.csproj.userไฟล์? เรากำลังพยายามที่จะทำตามอนุสัญญาที่ DLL ที่ขึ้นต่อกันอยู่ในที่เก็บ svn "การเผยแพร่" และโครงการทั้งหมดชี้ไปที่รุ่นใดรุ่นหนึ่ง เนื่องจากนักพัฒนาที่แตกต่างกันมีโครงสร้างโฟลเดอร์ที่แตกต่างกันการอ้างอิงแบบสัมพัทธ์จึงใช้ไม่ได้ดังนั้นเราจึงจัดทำโครงร่างเพื่อใช้ตัวแปรสภาพแวดล้อมที่ชี้ไปยังโฟลเดอร์รีลีสของนักพัฒนาโดยเฉพาะเพื่อสร้างการอ้างอิงแบบสัมบูรณ์ ดังนั้นหลังจากเพิ่มการอ้างอิงแล้วเราจะแก้ไขไฟล์โปรเจ็กต์ด้วยตนเองเพื่อเปลี่ยนการอ้างอิงเป็นพา ธ สัมบูรณ์โดยใช้ตัวแปรสภาพแวดล้อม

ฉันสังเกตเห็นว่าสิ่งนี้สามารถทำได้ทั้งกับHintPathและReferencePathแต่ความแตกต่างเดียวที่ฉันพบระหว่างพวกเขาHintPathคือได้รับการแก้ไขในเวลาสร้างและReferencePathเมื่อโครงการถูกโหลดลงใน IDE ฉันไม่แน่ใจจริงๆว่าส่วนแบ่งของสิ่งนั้นคืออะไร ฉันสังเกตเห็นว่าบางครั้ง VS เขียนซ้ำ.csproj.userและฉันต้องเขียนใหม่ReferencePathแต่ฉันไม่แน่ใจว่าอะไรทำให้เกิดสิ่งนั้น

ฉันได้ยินมาว่าไม่ควรตรวจสอบใน.csproj.userไฟล์เนื่องจากเป็นไฟล์เฉพาะผู้ใช้ดังนั้นฉันจึงต้องการตั้งเป้าหมาย แต่ฉันได้ยินมาว่าHintPathDLL ที่ระบุไม่ "รับประกัน" ว่าจะโหลดได้หาก DLL เดียวกันเช่นอยู่ในไดเรกทอรีผลลัพธ์ของโครงการ มีความคิดเห็นเกี่ยวกับเรื่องนี้ไหม

คำตอบ:


133

ตามบล็อก MSDN นี้: https://blogs.msdn.microsoft.com/manishagarwal/2005/09/28/resolving-file-references-in-team-build-part-2/

มีลำดับการค้นหาสำหรับแอสเซมบลีเมื่อสร้าง ลำดับการค้นหามีดังนี้:

  • ไฟล์จากโครงการปัจจุบัน - ระบุโดย $ {CandidateAssemblyFiles}
  • คุณสมบัติ $ (ReferencePath) ที่มาจากไฟล์. user / target
  • % (HintPath) ข้อมูลเมตาที่ระบุโดยรายการอ้างอิง
  • ไดเร็กทอรีกรอบเป้าหมาย
  • ไดเรกทอรีที่พบในรีจิสทรีที่ใช้การลงทะเบียน AssemblyFoldersEx
  • โฟลเดอร์แอสเซมบลีที่ลงทะเบียนซึ่งระบุโดย $ {AssemblyFolders}
  • $ (OutputPath) หรือ $ (OutDir)
  • GAC

ดังนั้นหากHintPathพบแอสเซมบลีที่ต้องการแต่สามารถพบแอสเซมบลีอื่นได้โดยใช้ReferencePathมันจะชอบแอสเซมบลีReferencePath 'd กับHintPath ' d หนึ่ง


2
ยกเว้นพวกเขาเปลี่ยนสิ่งนี้ใน VS2019 - เราใช้การตั้งค่านี้มาหลายปีแล้ว ไม่อีกแล้ว. ขณะนี้ไฟล์ที่เก็บมีลำดับความสำคัญสูงกว่าการสร้างไฟล์ dll โซลูชัน - ไปที่รูป :(
Christian

@ คริสเตียน: ไฟล์ที่เก็บคืออะไร? คุณมีข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้หรือไม่?
ทดสอบ

@ การทดสอบฉันกำลังพูดถึงเส้นทางอ้างอิงภายนอกคุณสามารถตั้งค่าในการตั้งค่าโครงการ 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 แตกต่างกันเล็กน้อยโดยใช้ $ (OutputPath) แทน $ (OutDir)

บนเครื่องของฉันฉันมีไฟล์ 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

ประสบการณ์ของฉันเองคือควรยึดตามการอ้างอิงการประกอบหนึ่งในสองประเภท:

  • แอสเซมบลี 'local' ในไดเร็กทอรี build ปัจจุบัน
  • การประกอบใน GAC

ฉันพบ (เหมือนที่คุณอธิบายไว้) วิธีการอื่น ๆ อาจจะเสียง่ายเกินไปหรือมีข้อกำหนดในการบำรุงรักษาที่น่ารำคาญ

แอสเซมบลีใด ๆ ที่ฉันไม่ต้องการ GAC ต้องอยู่ในไดเร็กทอรีการดำเนินการ แอสเซมบลีใด ๆ ที่ไม่ใช่หรือไม่สามารถอยู่ในไดเร็กทอรีการดำเนินการ I GAC (จัดการโดยเหตุการณ์สร้างอัตโนมัติ)

สิ่งนี้ยังไม่ทำให้ฉันมีปัญหาใด ๆ แม้ว่าฉันจะแน่ใจว่ามีสถานการณ์ที่ใช้ไม่ได้ แต่คำตอบปกติสำหรับปัญหาคือ "โอ้แค่ปิดมัน!" 8 ง

หวังว่าจะช่วยได้!


1

แม้ว่านี่จะเป็นเอกสารเก่า แต่ก็ช่วยฉันแก้ปัญหา 'HintPath' ถูกละเว้นในเครื่องอื่น เป็นเพราะ DLL ที่อ้างอิงจำเป็นต้องอยู่ในการควบคุมแหล่งที่มาด้วย:

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

ข้อความที่ตัดตอนมา:

เพื่อรวมและอ้างอิงการประกอบระบบภายนอก
1. ใน Solution Explorer คลิกขวาที่โปรเจ็กต์ที่ต้องการอ้างอิงแอสเซมบลีแล้วคลิกเพิ่มรายการที่มีอยู่
2. เรียกดูแอสเซมบลีจากนั้นคลิกตกลง จากนั้นแอสเซมบลีจะถูกคัดลอกลงในโฟลเดอร์โปรเจ็กต์และเพิ่มไปยัง VSS โดยอัตโนมัติ (สมมติว่าโปรเจ็กต์อยู่ภายใต้การควบคุมซอร์ส)
3. ใช้ปุ่มเรียกดูในกล่องโต้ตอบเพิ่มการอ้างอิงเพื่อตั้งค่าการอ้างอิงไฟล์ไปยังแอสเซมบลีในโฟลเดอร์โครงการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.