webentwicklung-frage-antwort-db.com.de

Einschließen von Inhaltsdateien in .csproj, die sich außerhalb des Projektkegels befinden

Ich habe ein C # -Projekt, sagen Sie MyProject.csproj unter "C:\Projects\MyProject \". Ich habe auch Dateien, die ich in das Ausgabeverzeichnis dieses Projekts kopieren möchte. Die Dateien befinden sich jedoch am Speicherort "C:\MyContentFiles \", d. H. Sie befinden sich NICHT innerhalb des Projektkegels. Dieses Verzeichnis hat auch Unterverzeichnisse. Der Inhalt des Verzeichnisses wird nicht verwaltet. Daher muss ich alles, was darunter ist, einschließen.

Wenn ich sie als 'Inhalt' in das Projekt einbeziehe, werden sie kopiert, die Verzeichnisstruktur geht jedoch verloren. Ich habe so etwas gemacht: -

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

Wie kopiere ich diese Dateien/Verzeichnisse rekursiv in das Ausgabeverzeichnis des Projekts, wobei die Verzeichnisstruktur erhalten bleibt?

64
Poulo

Sie müssen eine Datei als Link hinzufügen:

  1. Klicken Sie mit der rechten Maustaste auf das Projekt in VS.
  2. Hinzufügen -> Vorhandenes Element ...
  3. Finde die Datei.
  4. Wählen Sie es aus und.
  5. Fügen Sie als Link hinzu (klicken Sie im Dialogfeld auf die Schaltfläche "Hinzufügen").
  6. Öffnen Sie die Eigenschaften der Datei und setzen Sie "In Ausgabeverzeichnis kopieren" auf "Immer kopieren".

ABER Sie können es nicht für die Verzeichnisstruktur tun.
Stattdessen müssen Sie eine Post-Build-Aufgabe dafür schreiben. Dies ist ein Beispiel das dich zum Staunen bringt.

40

Ich glaube, dass @Dmytrii es auf der einen Seite richtig macht - Sie möchten die "Link" -Funktion verwenden.

Es ist jedoch nur teilweise richtig, wenn Sie sagen, dass Sie keine Verknüpfung zu einer Verzeichnisstruktur herstellen können Dies trifft zwar zu, wenn Sie versuchen, die Verknüpfungen mithilfe der Visual Studio-GUI hinzuzufügen. MSBuild unterstützt dies.

Wenn Sie die Verzeichnisstruktur beibehalten möchten, fügen Sie einfach den %(RecursiveDir)-Tag zu Ihrem <link>-Knoten hinzu:

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

Die Seite MSBuild Bekannte Elementmetadaten führt detailliertere Metadaten auf, auf die Sie zugreifen können.

125
Mandark

Die Antwort von Mandark fügt die Inhaltsdateien direkt zur Lösung hinzu und sie werden im Lösungs-Explorer angezeigt. Wenn eine Datei im ursprünglichen Verzeichnis hinzugefügt oder gelöscht wird, wird diese nicht automatisch von Visual Studio abgerufen. Immer, wenn eine Datei im Projektmappen-Explorer gelöscht oder hinzugefügt wird, wird die Projektdatei geändert und alle Dateien werden separat und nicht nur mit dem Ordner eingefügt.

Um dies zu verhindern, können Sie denselben Trick verwenden, ihn jedoch in eine separate Projektdatei packen und dann importieren.

Die Projektdatei (zum Beispiel include.proj) sieht folgendermaßen aus:

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

Fügen Sie in Ihrer eigenen Projektdatei die folgende Zeile hinzu

<Import Project="include.proj" />

Visual Studio verwirrt sich nicht mit dieser Datei und fügt Dateien während eines Builds nur als Inhalt hinzu. Änderungen im ursprünglichen Verzeichnis sind immer enthalten. Die Dateien werden nicht im Lösungs-Explorer angezeigt, sondern im Ausgabeverzeichnis enthalten.

Dieser Trick wurde hier aufgenommen: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx

25

Folgendes, das Sie am Ende Ihrer Projektdatei hinzufügen würden, kopiert Ihre Inhaltsdateien, wobei die Verzeichnisstruktur in einem After-Build-Ereignis beibehalten wird, in das Zielverzeichnis $(TargetDirectory) Ihres Builds (normalerweise $(MSBuildProjectDirectory)\bin\Debug). 

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

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

Wenn diese Dateien in ein Verzeichnis namens MyContentFiles verschoben werden müssen, können Sie dies vor der Kopie hinzufügen:

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

und ändern

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

Zu

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

Meiner Ansicht nach 

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

Ist gerade genug, da Sie alles in diesem Ordner und Unterordner haben wollen

3
Menzi

Um Dateien in einen Ordner für ein .NET Core-Projekt aufzunehmen,

<ItemGroup>
  <None Update="..\..\MyContentFiles\**\*.*">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

Die Eigenschaft "Artikel in Ausgabeverzeichnis kopieren" lautet "Kopieren, wenn neuer":
Copy if newer

0
zwcloud

So ignorieren Sie eine Datei in einem .Net Core-Projekt:

<ItemGroup>
 <Content Include="appsettings.local.json">
   <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory>
 </Content>
</ItemGroup>
0