2012-04-18 11 views
8

Czy można podać inny folder dla pliku wyjściowego następującego pliku?Czy mogę określić ścieżkę wyjściową dla znacznika MSBuild <Content>?

<Content Include="test.stl"> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
</Content> 
+0

dowiedziałeś się, jak to zrobić? –

+0

Jeszcze nie, przepraszam. – abenci

+1

Ten link nie pokazuje, jak określić inny folder z tagiem treści, ale wygląda na obejście, które może pozwolić ci na robienie tego, co chcesz ... http://stackoverflow.com/questions/7643615/how-can- i-get-msbuild-to-copy-all-files-oznaczone-jako-treść-do-folderu-preservin –

Odpowiedz

5

Możesz, ale nie "Treść". To zależy od zadania przedmiotu, ale większość wbudowanych elementów, w które można włamać się, jest warta kłopotów lub efektów ubocznych.

Istnieje podstawowa dobrze zużytą ścieżkę do radzenia sobie z tym :) Zapobiega to także paskudnemu PostBuildowi powłoki cmd, jeśli robisz .Net, i używa procesu budowania aktorskiego.

Nie widziałem żadnych innych odpowiedzi w ten sposób, korzystając z MSBuild, gdzie myślę, że serce pytania jest OP. Jest to podstawowa koncepcja i najkrótsza ścieżka, odsłaniając typ elementu, który ma parametr ścieżki względem ścieżki wyjściowej bez efektów ubocznych.

1) post Process Styl:

<ItemGroup> 
    ... 
    <MyTargets Include="test.stl"/> 
    ... 
</ItemGroup> 

Następnie na dole (przy użyciu cokolwiek ścieżki jesteś po):

<PropertyGroup> 
    <MyDeployDir>$(SolutionDir)$(Configuration)</MyDeployDir> 
    <MyOtherDeployDir>$(SolutionDir)$(Configuration)\Templates</MyDeployDir> 
</PropertGroup> 

Wtedy twój istniejący build MS obejmuje (nie dodawać tego, jest tutaj jako znacznik):

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> 

Następnie „Po budowie”:

<Target Name="AfterBuild"> 
    <Copy SourceFiles="@(MyTargets)" DestinationFolder="$(MyDeployDir)" SkipUnchangedFiles="true" /> 
    <Copy SourceFiles="@(MyOtherTargets)" DestinationFolder="$(MyOtherDeployDir)" SkipUnchangedFiles="true" /> 
    <Copy SourceFiles="@(MyTargets2)" DestinationFolder="$(MyDeployDir)\IHeardYourMomLikesGrapeNuts" SkipUnchangedFiles="true" /> 
</Target> 

fundemental problemem jest to, że projekt przedmioty nie robić nic domyślnie mają typ jak „Content” lub „MyTarget”. To te typy, które mówią, co się stanie. Możesz znaleźć zadanie, wpisać lub skompilować skrypt, który ma to, czego chcesz, ale nie ma nic nieodłącznego w stosunku do elementu w grupie item, jeśli chodzi o to, co stanie się z tym plikiem podczas kompilacji. Powyższe stanowi równowagę pomiędzy mocą specjalnie zbudowanego "zadania", ale bez żadnych problemów.

Po dodaniu

<ItemGroup> 
    <MyOutFiles Include="xxx.xxx" /> 

raz do pliku projektu, to wtedy pojawi się na liście BuildAction dla każdego pliku, w którym można ustawić na dowolnym pliku bez konieczności ręcznej edycji pliku proj.


2) w jednym kroku

W późniejszych wersjach MSBuild można osadzić „ItemGroup” wewnątrz wyznaczonego przez „AfterBuild” i zrobić powyżej lub robić inne wymyślne rzeczy bez dotykania reszty pliku . Pozwala to na przykład na pobranie wyniku z kompilacji za pomocą prostego Include i przeniesienia go gdzie indziej. To wszystko bez robienia RoboCopy czegokolwiek lub uciekania się do bardziej skomplikowanego przetwarzania funkcji celu kompilacji.

<Target Name="AfterBuild"> 
    <ItemGroup> 
    <MyOutFiles Include="$(OutDir)*.*" /> 
    </ItemGroup> 
    <Copy SourceFiles="@(MyOutFiles)" DestinationFolder="$(SolutionDir)\Application" SkipUnchangedFiles="true" /> 

Edit (z powodu głosowania w dół?, komentarz do plakatów, ponieważ usunięto):

Aby ujednoznacznić możliwe metody i powtórzyć, ta metoda nie używa funkcji MSBuilda ani alternatywnych zadań takich jak "RoboCopy", ale miała na celu pokazać bardziej czysty styl MSBuild przy użyciu podstawowych funkcji, takich jak można użyć do wykonywania zadań związanych z przedmiotami, takich jak "Treść".

Pytanie brzmiało, czy mogę określić "folder różni się dla następującego pliku" i czy mogę to zrobić dla tagu treści. Możesz przekierować wszystkie funkcje BuildAction przy użyciu MSBuild, jednak nie wierzę, że to było pytanie.

Możesz to zrobić w jednym kroku, jak pokazano powyżej, więc nie sądzę, że jest to bardziej skomplikowane i łatwiejsze do odczytania. Poniżej znajduje się krótki formularz, który pozwala mu stworzyć własną funkcję BuildAction, która może być obsługiwana tak, jak chce. Więc nie, nie możesz powiedzieć "Treści", aby wybrać inny folder dla konkretnego pliku oznaczonego jako "Treść", ale możesz wykonać kolejną akcję kompilacji, która działa dość łatwo. Możesz również wstawić meta-informacje do znacznika StlFiles, który kieruje działaniem, tak abyś mógł ustawić go na samym znaczniku lub aby haczyk StlFiles wcześniej działał w taki sposób, jak zawartość, ale to jest bardziej skomplikowane.

<StlFiles Include="test.stl" />   
... 
<Target Name="AfterBuild"> 
    <Copy SourceFiles="@(StlFiles)" DestinationFolder="$(SolutionDir)\Release\MyTypes" SkipUnchangedFiles="true" /> 
+0

Odpowiedź nie jest zła, działa.Podany link pokazuje inny sposób korzystania z funkcji skryptów, których unikam, na przykład unikanie zadania RoboCopy. Podany link rzuca całą zawartość na miejsce, robi to jeden plik. Poprosił o jeden plik. Pytanie brzmiało: czy zadanie elementu może używać alternatywnej ścieżki wyjściowej. Odpowiedź brzmi: tak i nie, treść nie może, ale inne zadania mogą, ale tutaj jest sposób na sprawdzenie, który można kontrolować. – Celess

+0

Nad moim pierwszym komentarzem pojawił się komentarz, który najwyraźniej usunięto; tylko powiedzenie ... więc powyższe nie wydaje się przypadkowe. To był komentarz do głosowania, na który odpowiadałem, i dlaczego sekcja edycji istnieje w odpowiedzi. Komentarz, który teraz zaginął, był dość silnie sformułowany, co skutkowało "głosowaniem w dół", ponieważ nie tylko ta odpowiedź jest błędna, ale czyni coś prostszego o wiele bardziej skomplikowanego niż to, na co "BitwiseMan". – Celess

+0

Link, do którego się odwołał: http://stackoverflow.com/questions/7643615/how-can-i-get-msbuild-to-copy-all-files-marked-as-content-to-a-folder-preservin – Celess

0

Nie ma sposobu na określenie folderu wyjściowego dodatkowo AFAIK, ale można skopiować plik przed lub po kompilacji.

0

Ta funkcja nie jest wbudowana w element treści. Ale możesz go dodać, dodając cel do pliku projektu.

W projekcie masz obecnie to:

<ItemGroup> 
    <Content Include="test.stl"> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
    </Content> 
</ItemGroup> 

Zakładając, że chcesz, że jeden konkretny plik kopiowany do innej lokalizacji, dodać to do końca (przed zamknięciem tagu „Projekt”):

<Target Name="CopyStl" AfterTargets="AfterBuild"> 
    <!-- One or the other of these Copy tasks should do what you want --> 
    <Copy Condition="'%(Identity)' == 'test.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(OutputPath)\path\under\outputpath" /> 
    <Copy Condition="'%(Identity)' == 'test.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(MSBuildProjectDirectory)\..\path\outside\project" /> 
</Target> 

Jeśli chcesz dodać kilka więcej plików skopiować do tego samego folderu, spróbuj zamiast tego:

<Target Name="CopySomeFiles" AfterTargets="AfterBuild"> 
    <!-- One or the other of these Copy tasks should do what you want --> 
    <Copy Condition="'%(Identity)' == 'test.stl' AND '%(Identity)' == 'test2.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(OutputPath)\path\under\outputpath" /> 
    <Copy Condition="'%(Identity)' == 'test.stl' AND '%(Identity)' == 'test2.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(MSBuildProjectDirectory)\..\path\outside\project" /> 
</Target 
0

inny folder wyjściowy może być określony za pomocą metadanych Link na None/Content przedmiotów:

<Content Include="test.stl"> 
    <Link>some\folder\%(Filename)%(Extension)</Link> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
</Content> 

Przy użyciu symboli wieloznacznych w instrukcji należą, jest to również sposób na zachowanie hierarchii katalogów, nawet dla plików pochodzących z poza katalogu projektu:

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

W projektach opartych SDK (domyślny dla projektów ASP.NET Rdzeń/NET Rdzeń/NET standard) Używanie 2.0.0+ SDK, to samo można osiągnąć za pomocą LinkBase metadane:

<Content Include="..\shared\**\*" LinkBase="some\folder" CopyToOutputDirectory="PreserveNewest" /> 
Powiązane problemy