การตั้งค่าส่วนตัวทำอะไรกับ ProjectReference ในไฟล์โครงการ MSBuild


120

ฉันเห็นสิ่งนี้ในไฟล์โครงการเมื่อวันก่อน:

<ProjectReference Include="Foo\Bar\Baz.csproj">
    <Project>{A GUID HERE}</Project>
    <Name>Baz</Name>
    <Private>False</Private> <!-- ??? -->
    <ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference>

ทุกโหนดใน a ProjectReferenceดูเหมือนจะอธิบายได้ด้วยตนเอง (ไฟล์โปรเจ็กต์อ้างอิง GUID ชื่อที่จะแสดงในตัวสำรวจโซลูชันและโปรเจ็กต์ปัจจุบันควรเชื่อมโยงกับโปรเจ็กต์ที่อ้างอิงหรือไม่) ยกเว้นPrivateและเพจCommon MSBuild Project Itemsไม่ ' t บันทึกค่านี้ (มีเป็นPrivateตั้งค่าเอกสารสำหรับReferenceมากกว่าProjectReference- แต่มันก็มีNever, AlwaysและPreserveNewestการตั้งค่าไม่เป็นความจริงและเท็จ)

การตั้งค่านี้ทำอะไร


2
เท่าที่ MSBuild เกี่ยวข้อง ProjectReference คือกลุ่มสินค้า (เช่นรายการ) และส่วนตัวคือข้อมูลเมตาของรายการสำหรับรายการที่รวม คำตอบสำหรับคำถามของคุณอยู่ที่ว่ามีอะไรบ้างที่เกี่ยวข้องกับคำถามนี้ โดยทั่วไปแล้วโครงการประเภทใดที่เฉพาะเจาะจงคืออะไร? อาจจะแท็กคำถามของคุณด้วย csharp
Tom Blodget

ฉันหมายถึง "การนำเข้า" ไม่ใช่ "รวม"
Tom Blodget

@malexander: ฉันคิดว่าคำตอบของคุณดีถ้าคุณจะยกเลิกการลบ ...
Billy ONeal

2
@ ทอม: แน่นอนว่าพูดอย่างเคร่งครัดว่าเป็นเรื่องจริง ในทางกลับกันProjectReferenceรายการได้รับการยอมรับโดย (อย่างน้อย) โครงสร้างพื้นฐานที่สนับสนุน C # และ C ++ MSBuild; ดูเหมือนว่าส่วนใหญ่จะจัดการในMicrosoft.Common.CurrentVersion.targetsไฟล์
Billy ONeal

คำตอบ:


126

Privateแท็กยังคงใช้แทนที่การ "คัดลอกท้องถิ่น" ช่องทำเครื่องหมายในภาพโฟลเดอร์อ้างอิงสตูดิโอ สิ่งนี้ควบคุมว่าจะใช้การอ้างอิงจาก GAC หรือว่าจะคัดลอกแอสเซมบลีที่อ้างอิงไปยังไดเร็กทอรีบิลด์

ในขณะที่ฉันไม่พบเอกสาร MSDN ใด ๆ สำหรับเอฟเฟกต์นี้ (แปลกใจแปลกใจ) เห็นได้ชัดจากพฤติกรรมและจากความคิดเห็นMicrosoft.Common.CurrentVersion.targets:1742ที่นำไปใช้:

เอกสารนี้อยู่ในMSDN> ไอเท็มโครงการ MSBuild ทั่วไปและเห็นได้ชัดจากพฤติกรรมและจากความคิดเห็นMicrosoft.Common.CurrentVersion.targets:1742ที่นำไปใช้:

  <!--
    ============================================================

                                        ResolveAssemblyReferences

    Given the list of assemblies, find the closure of all assemblies that they depend on. These are
    what we need to copy to the output directory.

        [IN]
        @(Reference) - List of assembly references as fusion names.
        @(_ResolvedProjectReferencePaths) - List of project references produced by projects that this project depends on.

            The 'Private' attribute on the reference corresponds to the Copy Local flag in IDE.
            The 'Private' flag can have three possible values:
                - 'True' means the reference should be Copied Local
                - 'False' means the reference should not be Copied Local
                - [Missing] means this task will decide whether to treat this reference as CopyLocal or not.

        [OUT]
        @(ReferencePath) - Paths to resolved primary files.
        @(ReferenceDependencyPaths) - Paths to resolved dependency files.
        @(_ReferenceRelatedPaths) - Paths to .xmls and .pdbs.
        @(ReferenceSatellitePaths) - Paths to satellites.
        @(_ReferenceSerializationAssemblyPaths) - Paths to XML serialization assemblies created by sgen.
        @(_ReferenceScatterPaths) - Paths to scatter files.
        @(ReferenceCopyLocalPaths) - Paths to files that should be copied to the local directory.
    ============================================================
    -->

7
ดังที่ Mitch กล่าวว่าควบคุมการตั้งค่า Copy Local ในคุณสมบัติสำหรับการอ้างอิง นอกจากนี้ยังสามารถมีได้เฉพาะค่าจริงและเท็จเท่านั้น หากไม่มีจะถือว่าค่าเริ่มต้นของ True
GPR

4
หาก<Private>หายไปแสดงว่าไม่เทียบเท่ากับTrue. ค้นหา "MSBuild CopyLocal bug" เช่นดูstackoverflow.com/questions/1132243
xmedeko

7
@xmedeko ถูกต้อง ฉันไม่แน่ใจว่า @GPR ได้ที่ไหน "หากไม่มีจะถือว่าค่าเริ่มต้นของ True" เนื่องจากคำตอบระบุไว้อย่างชัดเจนว่า "[Missing] หมายความว่างานนี้จะตัดสินใจว่าจะถือว่าการอ้างอิงนี้เป็น CopyLocal หรือไม่" ตรรกะส่วนใหญ่อยู่ในmsbuild\Reference.cs:949
Mitch

เป็นไปได้ไหมว่าแม้ว่า<Private>จะตั้งค่าเป็นTrueMSBuild ก็ยังไม่รวมการอ้างอิงในผลลัพธ์หากแอปพลิเคชันไม่ได้ใช้ นี่คือพฤติกรรมปัจจุบันที่ฉันได้รับในท้องถิ่น ...
Ninja

@Ninja สิ่งนี้เกิดขึ้นบ่อยที่สุดหาก MSBuild ไม่พบแอสเซมบลีที่อ้างอิง หากไม่ได้ใช้โค้ดโดยตรงโค้ดอาจยังคอมไพล์สำเร็จ คุณสามารถแก้ปัญหาด้วยการบันทึกโดยละเอียดprocmonหรือMSBuild
Mitch

0

ฉันต้องการเพียงแค่ให้อยู่ในสถานะที่<Private>false</Private>(ซึ่งคุณสามารถนำไปใช้กับProjectReferences) อาจไม่ทำงานเมื่อใช้<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Publish" Properties="$(_MSBuildProperties)" />และโครงการ$(MSBuildProjectFullPath)มีProjectReferences <None><CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory></None> ที่มี ฉันอ่านซอร์สโค้ดรอบ ๆhttps://github.com/dotnet/sdk/blob/master/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targetsและพบวิธีแก้ปัญหา คุณต้องกำหนด_GetChildProjectCopyToPublishDirectoryItems=falseตัวอย่างจึงจะเป็น:<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Publish" Properties="TargetFramework=$(TargetFramework);_GetChildProjectCopyToPublishDirectoryItems=false" />

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.