Mam projekt C #, powiedz MyProject.csproj znajdujący się w „C: \ Projects \ MyProject \”. Mam również pliki, które chcę skopiować do katalogu wyjściowego tego projektu. Ale pliki znajdują się w lokalizacji „C: \ MyContentFiles \”, tj. NIE znajdują się w obrębie stożka projektu. Ten katalog zawiera również podkatalogi. Zawartość katalogu nie jest zarządzana. Dlatego muszę uwzględnić wszystko, co się pod nim znajduje.
Kiedy dołączam je do projektu jako „Treść”, są one kopiowane, ale struktura katalogów zostaje utracona. Zrobiłem coś takiego: -
<Content Include="..\..\MyContentFiles\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Jak mogę rekurencyjnie skopiować te pliki / katalogi do katalogu wyjściowego projektu z zachowaną strukturą katalogów?
Uważam, że @Dmytrii robi to dobrze z jednej strony - chcesz użyć funkcji „łącza”.
Jednak tylko częściowo ma rację, mówiąc, że nie można dowiązać do drzewa katalogów. Chociaż jest to rzeczywiście prawdą, gdy próbujesz dodać linki przy użyciu graficznego interfejsu użytkownika programu Visual Studio, MSBuild to obsługuje.
Jeśli chcesz zachować strukturę katalogów, po prostu dodaj
%(RecursiveDir)
znacznik do swojego<link>
węzła:<Content Include="..\..\MyContentFiles\**\*.*"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>
Strona MSBuild Dobrze znane metadane elementu zawiera bardziej szczegółowe informacje na temat metadanych, do których można uzyskać dostęp.
źródło
<Content Include="..\..\MyContentFiles\**\*.*">
- zwróć uwagę\*.*
na koniec ścieżki.Odpowiedź Mandarka dodaje pliki zawartości bezpośrednio do rozwiązania i pojawią się one w eksploratorze rozwiązań. Za każdym razem, gdy plik jest dodawany lub usuwany w oryginalnym katalogu, nie jest on automatycznie pobierany przez program Visual Studio. Ponadto za każdym razem, gdy plik zostanie usunięty lub dodany w eksploratorze rozwiązań, plik projektu zostanie zmieniony, a wszystkie pliki są dołączane osobno, zamiast po prostu dołączać folder.
Aby temu zapobiec, możesz użyć tej samej sztuczki, ale umieścić ją w osobnym pliku projektu, a następnie zaimportować.
Plik projektu (na przykład include.proj) wygląda następująco:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Content Include="..\..\MyContentFiles\**"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> </Project>
W swoim własnym pliku projektu dodaj następujący wiersz
<Import Project="include.proj" />
Program Visual Studio nie będzie bałaganu z tym plikiem i po prostu dodaje pliki jako zawartość podczas kompilacji. Zmiany w oryginalnym katalogu są zawsze uwzględniane. Pliki nie pojawią się w eksploratorze rozwiązań, ale zostaną uwzględnione w katalogu wyjściowym.
Wykryto tę sztuczkę tutaj: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx
źródło
Poniższe elementy, które można dodać na końcu pliku projektu, skopiują pliki zawartości z zachowaniem struktury katalogów w zdarzeniu po kompilacji do katalogu docelowego
$(TargetDirectory)
kompilacji (zazwyczaj$(MSBuildProjectDirectory)\bin\Debug
).<ItemGroup> <ExtraContent Include="$(MSBuildProjectDirectory)\..\..\MyContentFiles\**" /> </ItemGroup> <Target Name="AfterBuild"> <Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" /> </Target>
Jeśli te pliki musiały znaleźć się w katalogu o nazwie MyContentFiles, możesz dodać to przed kopiowaniem:
<MakeDir Directories="$(TargetDir)\MyContentFiles" Condition=" !Exists('$(TargetDir\MyContentFiles') " />
i zmienić
<Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
Do
<Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
źródło
Myślę
<Content Include="..\..\MyContentFiles\**\*.*"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>
Wystarczy, ponieważ chcesz wszystko w tym folderze i podfolderach
źródło
Aby dołączyć pliki do folderu dla projektu .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>
Właściwość elementu „Kopiuj do katalogu wyjściowego” będzie miała wartość „Kopiuj, jeśli nowsza”:
źródło
Aby zignorować plik w projekcie .Net Core:
<ItemGroup> <Content Include="appsettings.local.json"> <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup>
źródło