รวมถึงไฟล์เนื้อหาใน. csproj ที่อยู่นอกกรวยโครงการ


86

ฉันมีโครงการ C # บอกว่า MyProject.csproj อยู่ที่ "C: \ Projects \ MyProject \" ฉันยังมีไฟล์ที่ต้องการคัดลอกไปยังไดเรกทอรีผลลัพธ์ของโครงการนี้ แต่ไฟล์จะอยู่ในตำแหน่ง "C: \ MyContentFiles \" นั่นคือไฟล์เหล่านี้ไม่ได้อยู่ในกรวยโครงการ ไดเร็กทอรีนี้มีไดเร็กทอรีย่อยด้วย ไม่มีการจัดการเนื้อหาของไดเร็กทอรี ดังนั้นฉันต้องรวมสิ่งที่อยู่ภายใต้มันทั้งหมด

เมื่อฉันรวมไว้เป็น 'เนื้อหา' ในโปรเจ็กต์สิ่งเหล่านี้จะถูกคัดลอก แต่โครงสร้างไดเร็กทอรีหายไป ฉันทำสิ่งนี้: -

<Content Include="..\..\MyContentFiles\**">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

ฉันจะคัดลอกไฟล์ / ไดเร็กทอรีเหล่านี้แบบวนซ้ำไปยังไดเร็กทอรีเอาต์พุตของโปรเจ็กต์ที่มีโครงสร้างไดเร็กทอรีอยู่ได้อย่างไร

คำตอบ:


56

คุณต้องเพิ่มไฟล์เป็นลิงค์:

  1. คลิกขวาที่โครงการใน VS.
  2. เพิ่ม -> รายการที่มีอยู่ ...
  3. ค้นหาไฟล์
  4. เลือกและ
  5. เพิ่มเป็นลิงก์ (เลื่อนลงในปุ่มเพิ่มในกล่องโต้ตอบ)
  6. เปิดคุณสมบัติของไฟล์และตั้งค่า "Copy to Output Directory" เป็น "Copy always"

แต่คุณไม่สามารถทำได้สำหรับแผนผังไดเรกทอรี
แต่คุณต้องเขียนงานหลังการสร้างสำหรับสิ่งนั้น นี่คือตัวอย่างที่จะทำให้คุณจ้องมอง


8
ตามที่ระบุไว้ในคำตอบนี้ "คุณไม่สามารถทำได้สำหรับแผนผังไดเรกทอรี" คำสั่งไม่เป็นความจริง
Mandark

164

ฉันเชื่อว่า@Dmytriiทำให้ถูกต้องในมือเดียว - คุณต้องการใช้คุณลักษณะ "ลิงก์"

อย่างไรก็ตามเขาถูกต้องเพียงบางส่วนเมื่อบอกว่าคุณไม่สามารถเชื่อมโยงไปยังแผนผังไดเรกทอรีได้ แม้ว่าจะเป็นจริงเมื่อพยายามเพิ่มลิงก์โดยใช้ GUI ของ Visual Studio แต่ MSBuild ก็สนับสนุนสิ่งนี้

หากคุณต้องการรักษาโครงสร้างไดเร็กทอรีเพียงเพิ่ม%(RecursiveDir)แท็กใน<link>โหนดของคุณ:

<Content Include="..\..\MyContentFiles\**\*.*">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

หน้า MSBuild ข้อมูลเมตาของรายการที่รู้จักกันดีจะให้รายละเอียดเพิ่มเติมเกี่ยวกับข้อมูลเมตาที่คุณสามารถเข้าถึงได้


1
1) จะเกิดอะไรขึ้นถ้าไฟล์ถูกลบออกจากที่เก็บ Shared Assets? ดูเหมือนว่าจะไม่ถูกลบออกจาก Solution Dir 2) มีวิธีใดบ้างที่จะทำให้ Visual Studio ลบไฟล์เหล่านี้จาก $ (SolutionDir) หลังจากการรันเสร็จสิ้น การทิ้งไว้ที่นั่นอาจทำให้นักพัฒนาคนอื่นสับสน
Adam

@Adam ดูคำตอบของฉันด้านล่าง
Robin van der Knaap

9
เมื่อถูกชนในถิ่นทุรกันดารโดยมีอาหารน้ำและความต้องการความเป็นเพื่อนที่ดีฉันพบว่าคำตอบนี้มีประโยชน์ ด้วยการทำตามคำแนะนำเหล่านี้ฉันสามารถสร้าง AI ที่ทำงานได้อย่างสมบูรณ์ซึ่งตอนนี้ได้แทนที่ความต้องการของมนุษย์ทั้งหมดที่เคยหลอกหลอนฉันในถิ่นทุรกันดาร ขอบคุณ Mandark!
deepelement

1
@Vijay ดูการแก้ไขของฉันคุณต้องการ<Content Include="..\..\MyContentFiles\**\*.*">- สังเกต\*.*ที่ท้ายเส้นทาง
CAD bloke

3
ไม่ทำงานกับโปรเจ็กต์. NET Core บน VS2017 (15.8.6)
zwcloud

29

คำตอบของMandarkจะเพิ่มไฟล์เนื้อหาลงในโซลูชันโดยตรงและจะปรากฏในตัวสำรวจโซลูชัน เมื่อใดก็ตามที่มีการเพิ่มหรือลบไฟล์ในไดเร็กทอรีดั้งเดิมสิ่งนี้จะไม่ถูกเลือกโดย Visual Studio โดยอัตโนมัติ นอกจากนี้เมื่อใดก็ตามที่ไฟล์ถูกลบหรือเพิ่มในตัวสำรวจโซลูชันไฟล์โปรเจ็กต์จะถูกเปลี่ยนแปลงและไฟล์ทั้งหมดจะรวมแยกกันแทนที่จะรวมเฉพาะโฟลเดอร์

เพื่อป้องกันปัญหานี้คุณสามารถใช้เคล็ดลับเดียวกัน แต่วางไว้ในไฟล์โครงการแยกต่างหากจากนั้นจึงนำเข้า

ไฟล์โครงการ (ตัวอย่างเช่น include.proj) มีลักษณะดังนี้:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="..\..\MyContentFiles\**">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

ในไฟล์โครงการของคุณเองให้เพิ่มบรรทัดต่อไปนี้

<Import Project="include.proj" />

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

รับเคล็ดลับนี้ที่นี่: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx


1
ด้วยเหตุผลบางอย่างดูเหมือนว่าฉันใช้ไฟล์. proj ไม่ได้ แต่ฉันสามารถทำให้มันใช้งานได้กับไฟล์. csproj
StriplingWarrior

6
คุณสามารถเพิ่ม <Visible> true </Visible> ในองค์ประกอบเนื้อหาเพื่อให้รายการปรากฏใน Solution Explorer
Michael Baker

ของฉันก็โอเคแค่.
proj

สิ่งนี้ไม่ได้ผลสำหรับฉันเลยและฉันคิดว่าเป็นเพราะไอเท็มที่จะเชื่อมโยงนั้นถูกสร้างขึ้นในเหตุการณ์ก่อนสร้าง
Paul K

2
ไม่ทำงานกับโปรเจ็กต์. NET Core บน VS2017 (15.8.6)
zwcloud

11

สิ่งต่อไปนี้ซึ่งคุณจะเพิ่มที่ด้านล่างของไฟล์โปรเจ็กต์ของคุณจะคัดลอกไฟล์เนื้อหาของคุณที่คงโครงสร้างไดเร็กทอรีไว้ในเหตุการณ์ after build ไปยังไดเร็กทอรีเป้าหมาย$(TargetDirectory)ของบิลด์ของคุณ (โดยทั่วไป$(MSBuildProjectDirectory)\bin\Debug)

<ItemGroup>
    <ExtraContent Include="$(MSBuildProjectDirectory)\..\..\MyContentFiles\**" />
</ItemGroup>

<Target Name="AfterBuild">
    <Copy 
        SourceFiles="@(ExtraContent)" 
        DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" 
        SkipUnchangedFiles="true" />
</Target>

หากไฟล์เหล่านี้จำเป็นต้องไปอยู่ในไดเร็กทอรีชื่อ MyContentFiles คุณสามารถเพิ่มสิ่งนี้ก่อนสำเนา:

<MakeDir Directories="$(TargetDir)\MyContentFiles" Condition=" !Exists('$(TargetDir\MyContentFiles') " />

และการเปลี่ยนแปลง

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />

ถึง

<Copy 
            SourceFiles="@(ExtraContent)" 
            DestinationFiles="@(ExtraContent->'$(TargetDir)\MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)')" 
            SkipUnchangedFiles="true" />

1
การแปลงของคุณมีประเภท -o: @ (ExtraContent) -> '... ') ควรเป็น @ (ExtraContext -> '... ') อย่างอื่นตอบดี!
alexdej

@Todd 1) จะเกิดอะไรขึ้นถ้าไฟล์ถูกลบออกจากที่เก็บ MyContentFiles? ดูเหมือนว่าจะไม่ถูกลบออกจาก Solution Dir 2) มีวิธีใดบ้างที่จะทำให้ Visual Studio ลบไฟล์เหล่านี้จาก $ (SolutionDir) หลังจากการรันเสร็จสิ้น การทิ้งไว้ที่นั่นอาจทำให้นักพัฒนาคนอื่นสับสน
Adam

นี่คือสิ่งที่ฉันต้องการ ขณะนี้โปรเจ็กต์และกระบวนการสร้างทำงานได้ตามที่คาดไว้ แต่ไฟล์จะไม่ถูกเผยแพร่ด้วยการคลิกเพียงครั้งเดียวแอปพลิเคชัน คำแนะนำใด ๆ สำหรับสิ่งนั้น?
Georg W.

4

ฉันคิด

<Content Include="..\..\MyContentFiles\**\*.*">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

ก็เพียงพอแล้วเนื่องจากคุณต้องการทุกอย่างในโฟลเดอร์และโฟลเดอร์ย่อยนั้น


3

ในการรวมไฟล์ในโฟลเดอร์สำหรับโปรเจ็กต์. NET Core

<!--Just files-->
<ItemGroup>
  <None Update="..\..\MyContentFiles\**\*.*">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>
<!--Content files-->
<ItemGroup>
  <Content Include="..\..\MyContentFiles\**\*.*" Link="MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

และคุณสมบัติของรายการ "Copy to Output Directory" จะเป็น "Copy if newer":
คัดลอกถ้าใหม่กว่า


-1

หากต้องการละเว้นไฟล์ในโครงการ. Net Core:

<ItemGroup>
 <Content Include="appsettings.local.json">
   <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory>
 </Content>
</ItemGroup>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.