Zastanawiam się tylko, czy ktoś mógłby mi pomóc z kilkoma skryptami msbuild, które próbuję napisać. To, co chciałbym zrobić, to skopiować wszystkie pliki i podfoldery z folderu do innego folderu za pomocą msbuild.
{ProjectName}
|----->Source
|----->Tools
|----->Viewer
|-----{about 5 sub dirs}
To, co muszę zrobić, to skopiować wszystkie pliki i podfoldery z folderu narzędzi do folderu debugowania aplikacji. To jest kod, który mam do tej pory.
<ItemGroup>
<Viewer Include="..\$(ApplicationDirectory)\Tools\viewer\**\*.*" />
</ItemGroup>
<Target Name="BeforeBuild">
<Copy SourceFiles="@(Viewer)" DestinationFolder="@(Viewer->'$(OutputPath)\\Tools')" />
</Target>
Skrypt kompilacji działa, ale nie kopiuje żadnych plików ani folderów.
Dzięki
scripting
msbuild
build-process
build
Nathan W.
źródło
źródło
%(RecursiveDir)
do folderu docelowego odtworzy strukturę katalogów. W przeciwnym razie wyjście jest płaskie. To jest najlepsza odpowiedź.%(RecursiveDir)
w MSBuild dobrze znane metadane elementu : docs.microsoft.com/en-us/visualstudio/msbuild/ ...Myślę, że problem może tkwić w tym, jak tworzysz ItemGroup i wywołujesz zadanie kopiowania. Sprawdź, czy to ma sens:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> <PropertyGroup> <YourDestinationDirectory>..\SomeDestinationDirectory</YourDestinationDirectory> <YourSourceDirectory>..\SomeSourceDirectory</YourSourceDirectory> </PropertyGroup> <Target Name="BeforeBuild"> <CreateItem Include="$(YourSourceDirectory)\**\*.*"> <Output TaskParameter="Include" ItemName="YourFilesToCopy" /> </CreateItem> <Copy SourceFiles="@(YourFilesToCopy)" DestinationFiles="@(YourFilesToCopy->'$(YourDestinationDirectory)\%(RecursiveDir)%(Filename)%(Extension)')" /> </Target> </Project>
źródło
CreateItem
zadanie jest przestarzałe. regex ma alternatywę. msdn.microsoft.com/en-us/library/s2y3e43x.aspxJestem trochę nowy w MSBuild, ale uważam, że zadanie EXEC jest przydatne w takich sytuacjach. Spotkałem się z tym samym wyzwaniem w moim projekcie i to zadziałało i było znacznie prostsze. Niech ktoś mi powie, jeśli to nie jest dobra praktyka.
<Target Name="CopyToDeployFolder" DependsOnTargets="CompileWebSite"> <Exec Command="xcopy.exe $(OutputDirectory) $(DeploymentDirectory) /e" WorkingDirectory="C:\Windows\" /> </Target>
źródło
Copy
zadania zamiast polecenia, jest kompatybilność. Wcześniej budowałem na Linuksie przy użyciu Mono i oczywiściexcopy
tam nie działa.<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> <PropertyGroup> <YourDestinationDirectory>..\SomeDestinationDirectory</YourDestinationDirectory> <YourSourceDirectory>..\SomeSourceDirectory</YourSourceDirectory> </PropertyGroup> <Target Name="BeforeBuild"> <CreateItem Include="$(YourSourceDirectory)\**\*.*"> <Output TaskParameter="Include" ItemName="YourFilesToCopy" /> </CreateItem> <Copy SourceFiles="@(YourFilesToCopy)" DestinationFiles="$(YourFilesToCopy)\%(RecursiveDir)" /> </Target> </Project>
\**\*.*
pomóc pobrać pliki z całego folderu. RecursiveDir pomaga umieścić cały plik w odpowiednim folderze ...źródło
CreateItem
zadanie jest przestarzałe. regex ma alternatywę. msdn.microsoft.com/en-us/library/s2y3e43x.aspxCzy próbowałeś określić konkretny katalog docelowy zamiast
Nie jestem biegły w zaawansowanej składni MSBuild, ale
wygląda dla mnie dziwnie. Skrypt wygląda dobrze, więc problem może dotyczyć wartości
$(ApplicationDirectory)
i$(OutputPath)
EDYTOWAĆ:
Oto post na blogu, który może być przydatny:
Instrukcje: rekurencyjne kopiowanie plików za pomocą zadania
źródło
Oto przykład, który zadziałał:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <MySourceFiles Include="c:\MySourceTree\**\*.*"/> </ItemGroup> <Target Name="CopyFiles"> <Copy SourceFiles="@(MySourceFiles)" DestinationFiles="@(MySourceFiles->'c:\MyDestinationTree\%(RecursiveDir)%(Filename)%(Extension)')" /> </Target> </Project>
źródło: https://msdn.microsoft.com/en-us/library/3e54c37h.aspx
źródło
To jest zadanie kopiowania, którego użyłem w moim własnym projekcie, działało idealnie dla mnie, pomyślnie kopiując folder z podfolderami do miejsca docelowego:
<ItemGroup > <MyProjectSource Include="$(OutputRoot)/MySource/**/*.*" /> </ItemGroup> <Target Name="AfterCopy" AfterTargets="WebPublish"> <Copy SourceFiles="@(MyProjectSource)" OverwriteReadOnlyFiles="true" DestinationFolder="$(PublishFolder)api/% (RecursiveDir)"/>
W moim przypadku skopiowałem folder publikacji projektu do innego folderu docelowego, myślę, że jest to podobne do twojego przypadku.
źródło
Osobiście korzystałem z CopyFolder, który jest częścią biblioteki zadań SDC.
http://sdctasks.codeplex.com/
źródło
Najlepszym sposobem rekurencyjnego kopiowania plików z jednego katalogu do innego przy użyciu programu MSBuild jest użycie zadania kopiowania z parametrami SourceFiles i DestinationFiles. Na przykład - Aby skopiować wszystkie pliki z katalogu kompilacji do katalogu kopii zapasowej, będzie
<PropertyGroup> <BuildDirectory Condition="'$(BuildDirectory)' == ''">Build</BuildDirectory> <BackupDirectory Condition="'$(BackupDiretory)' == ''">Backup</BackupDirectory> </PropertyGroup> <ItemGroup> <AllFiles Include="$(MSBuildProjectDirectory)/$(BuildDirectory)/**/*.*" /> </ItemGroup> <Target Name="Backup"> <Exec Command="if not exist $(BackupDirectory) md $(BackupDirectory)" /> <Copy SourceFiles="@(AllFiles)" DestinationFiles="@(AllFiles-> '$(MSBuildProjectDirectory)/$(BackupDirectory)/%(RecursiveDir)/%(Filename)% (Extension)')" /> </Target>
Teraz w powyższym poleceniu Kopiuj przechodzą wszystkie katalogi źródłowe, a pliki są kopiowane do katalogu docelowego.
źródło
Jeśli pracujesz z typowym łańcuchem narzędzi C ++, innym sposobem jest dodanie plików do standardowej listy CopyFileToFolders
<ItemGroup> <CopyFileToFolders Include="materials\**\*"> <DestinationFolders>$(MainOutputDirectory)\Resources\materials\%(RecursiveDir)</DestinationFolders> </CopyFileToFolders> </ItemGroup>
Poza tym, że jest to proste, jest to przyjemny sposób, ponieważ zadanie CopyFilesToFolders wygeneruje odpowiednie dane wejściowe, wyjściowe, a nawet pliki TLog, dzięki czemu operacje kopiowania będą wykonywane tylko wtedy, gdy jeden z plików wejściowych ulegnie zmianie lub brakuje jednego z plików wyjściowych. Z TLog, Visual Studio również poprawnie rozpozna projekt jako „aktualny” lub nie (używa do tego oddzielnego mechanizmu U2DCheck).
źródło