On windows I use this command :
<PropertyGroup>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<PreBuildEvent>IF NOT EXIST "$(TargetDir)DataFiles" MKDIR "$(TargetDir)DataFiles"</PreBuildEvent>
<PostBuildEvent>FOR /R "$(SolutionDir)\Api.Tests\Scenarios" %25%25f IN (*.json) DO COPY "%25%25f" "$(TargetDir)DataFiles\" /Y</PostBuildEvent>
</PropertyGroup>
On linux , I have this kind of error
Build FAILED.
[12:44:39][Step 1/1]
[12:44:39][Step 1/1] /usr/share/dotnet/sdk/2.1.302/Microsoft.Common.CurrentVersion.targets(1331,5): error MSB3073: The command "IF NOT EXIST "DataFiles" MKDIR "DataFiles"" exited with code 127. [/opt/jetbrains/buildAgent/work/4fc9032bf5656724/Api.Tests/Api.Tests/IApi.Tests.csproj]
[12:44:39][Step 1/1] 0 Warning(s)
[12:44:39][Step 1/1] 1 Error(s)
PreBuildEvent and PostBuildEvent are executed using the operating system's shell--cmd.exe on Windows and /bin/sh on macOS and Linux. Since those shells have different syntax, you'll have to do something different to be cross-platform compatible.
Options:
$(MSBuild::IsOSUnixLike())).I strongly prefer the latter. It'd look something like
<Target Name="CopyScenarios">
<ItemGroup>
<Scenarios Include="$(SolutionDir)\Api.Tests\Scenarios\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(Scenarios)"
DestinationFiles="@(Scenarios->'$(TargetDir)DataFiles\%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true" />
</Target>
it is helped. there are no errors
but Folder still not creates
I have investigated and notice that $(SolutionDir) --> Undefined/Api.Tests/Scenarios/
fixid by replace $(SolutionDir) to $(ProjectDir)
<Target Name="CopyScenarios" AfterTargets="Build">
<ItemGroup>
<Scenarios Include="$(ProjectDir)/Scenarios/**/*.json" />
</ItemGroup>
<Copy SourceFiles="@(Scenarios)" DestinationFiles="@(Scenarios->'$(TargetDir)DataFiles/%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
</Target>
$(SolutionDir) is set only when building _in the context of a solution_, so it's generally set in Visual Studio and for command line builds like msbuild.exe path\to\a.sln but _isn't_ set in command line builds like msbuild.exe path\to\a.csproj.
Sounds like you found a property that works for you, but there are some other options that may help: https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-reserved-and-well-known-properties
Some more options: You could also do
<ItemGroup>
<ContentWithTargetPath Include="Scenarios/**/*.json"
TargetPath="DataFiles/%(Filename)%(Extension)"
CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
directly in the project file.
Another alternative would be to update the files you already have, presumably None items:
<ItemGroup>
<None Update="Scenarios/**/*.json"
LinkBase="DataFiles/"
CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
(if the files aren't in your project directory, use Include="../shared/Scenarios/**/*.json" instead)
which however will display the items beneath a DataFiles folder in VS' solution explorer and hide the source folder structure if you are using VS.
@dasMulli Thanks, your approach works moreover it works with publishing
In prev variant, I used two Targets for build and for publishing
Can you give a link for documentation where I can read about keywords like "ContentWithTargetPath" and so one?
Most helpful comment
Some more options: You could also do
directly in the project file.
Another alternative would be to update the files you already have, presumably
Noneitems:(if the files aren't in your project directory, use
Include="../shared/Scenarios/**/*.json"instead)which however will display the items beneath a
DataFilesfolder in VS' solution explorer and hide the source folder structure if you are using VS.