MSbuild batching -- recursive folder copy to multiple destination folders - recursion

I am running into a situation. I am trying to use MSBuild batching to copy a folder (subdirectories as well as files) to mutilple dest folders.
but when i run the below script, it dumps every content from the src (contents from sub directories too) in root target directory, whereas what i was looking was to get the exact same structure as in src in the target dirs.
<PropertyGroup>
<Srcfldr>C:\helloworld\REService</Srcfldr>
<DestFldr>C:\Projects\desire\Examples</DestFldr>
</PropertyGroup>
<ItemGroup>
<SrcToCopy Include="$(Srcfldr)\*.*"/>
</ItemGroup>
<ItemGroup>
<DestToCopy Include="$(DestFldr)/destfldr1"/>
<DestToCopy Include="$(DestFldr)/destfldr2"/>
<DestToCopy Include="$(DestFldr)/destfldr3"/>
</ItemGroup>
<Target Name="DeployBatching">
<RemoveDir Directories="#(DestToCopy)"/>
<MakeDir Directories="#(DestToCopy)"/>
<Copy SourceFiles="#(SrcToCopy)" DestinationFolder="%(DestToCopy.FullPath)" />
Can you please tell me what am i doing wrong ...
SK

Vanilla copy task is better suited for copying files rather than directories, in any case to preserve structure you need to remap destination using %(RecursiveDir) and %(Filename)%(Extension) metadata. See second example on MSDN.
Edit:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Srcfldr>C:\helloworld\REService</Srcfldr>
<DestFldr>C:\Projects\desire\Examples</DestFldr>
</PropertyGroup>
<ItemGroup>
<SrcToCopy Include="$(Srcfldr)\**\*"/>
</ItemGroup>
<ItemGroup>
<DestToCopy Include="$(DestFldr)\destfldr1"/>
<DestToCopy Include="$(DestFldr)\destfldr2"/>
<DestToCopy Include="$(DestFldr)\destfldr3"/>
</ItemGroup>
<Target Name="DeployBatching" Outputs="%(DestToCopy.FullPath)">
<PropertyGroup>
<DestToCopy>%(DestToCopy.FullPath)</DestToCopy>
</PropertyGroup>
<RemoveDir Directories="#(DestToCopy)"/>
<MakeDir Directories="#(DestToCopy)"/>
<Copy
SourceFiles="#(SrcToCopy)"
DestinationFiles="#(SrcToCopy->'$(DestToCopy)\%(RecursiveDir)\%(Filename)%(Extension)')"
/>
</Target>
</Project>

Doesn't look like it's working the way i wanted it to ... I tried the below code
<PropertyGroup>
<Srcfldr>C:\helloworld\REService</Srcfldr>
<DestFldr>C:\Projects\desire\Examples</DestFldr>
</PropertyGroup>
<ItemGroup>
<SrcToCopy Include="$(Srcfldr)\*.*"/>
</ItemGroup>
<ItemGroup>
<DestToCopy Include="$(DestFldr)/destfldr1"/>
<DestToCopy Include="$(DestFldr)/destfldr2"/>
<DestToCopy Include="$(DestFldr)/destfldr3"/>
</ItemGroup>
<PropertyGroup>
<DestToCopyvar>%(DestToCopy)</DestToCopyvar>
</PropertyGroup>
<Target Name="DeployBatching">
<Copy SourceFiles="#(SrcToCopy)" DestinationFiles="#(SrcToCopy->'$(DestToCopyvar)\%(RecursiveDir)%(Filename)%(Extension)')" />
It's copying just the root files in the root directory, it is missing the directories and sub directories al together ...

This seems to be working for me now ...
<PropertyGroup>
<Srcfldr>C:\Msbuild\exproj\Rebinaries</Srcfldr>
<copyfldr>c$\component1</copyfldr>
</PropertyGroup>
<ItemGroup>
<SrcToCopy Include="$(Srcfldr)\**\*"/>
</ItemGroup>
<ItemGroup>
<DestToCopy Include="\\devsvr1\$(copyfldr);\\devsvr2\$(copyfldr)"/>
</ItemGroup>
<Target Name="DeployBatching" Outputs="%(DestToCopy.FullPath)">
<PropertyGroup>
<DestToCopy>%(DestToCopy.FullPath)</DestToCopy>
</PropertyGroup>
<RemoveDir Directories="#(DestToCopy)"/>
<MakeDir Directories="#(DestToCopy)"/>
<Copy
SourceFiles="#(SrcToCopy)"
DestinationFiles="#(SrcToCopy->'$(DestToCopy)\%(RecursiveDir)\%(Filename)%(Extension)')"
/>
</Target>

Related

Xamarin.Forms SDK-Style multiplatform project with XAML

Have defined multitarget project:
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;xamarinios10;monoandroid9.0;</TargetFrameworks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="4.6.0.800" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3" />
<Compile Include="**\Shared\*.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('xamarinios')) ">
<Compile Include="**\iOS\*.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('monoandroid')) ">
<Compile Include="**\Android\*.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Shared\MyView.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>
So, when i make my custom component only in code all compile and works well, but i would like to develop some custom controls using XAML.
But i got error of ambiguous call to method InitializeComponent() in MyView object.
How to make correct conditional configuration in .csproj for compiler to understand *.xaml and *.xaml.cs files ?
Adding these properties to common ItemGroup solved the problem:
<None Remove="**\Shared\*.xaml" />
<Compile Include="**\Shared\*.xaml.cs" DependentUpon="%(Filename)" />
<EmbeddedResource Include="**\Shared\*.xaml" Generator="MSBuild:UpdateDesignTimeXaml" />

Call awaited database context methods in F#

I have defined a context (inherited from DbContext) and in C# I use:
await _context.People.SingleOrDefaultAsync()
But having the context in the F# code, the *Async methods don't exist:
_context.People...
How can I call SingleOrDefaultAsync?
I am using Entity Framework Core.
This is my .fsproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="PeopleQuery.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Domain.People.csproj" />
</ItemGroup>
</Project>

NLog.config Transformation

I have an NLog.config file that I want transformed before publishing my site. Similar to how web.config is transformed. How do I accomplish this? I couldn't find any solid resources on how to do this.
I tried adding a transform to the csproj
<Target Name="BeforeBuild" Condition="exists('NLog.$(Configuration).config')">
<Message Text="Tranforming NLog..."/>
<TransformXml Source="NLog.config" Transform="NLog.$(Configuration).config" Destination="$(OutputPath)\NLog.config" />
</Target>
Also added the NLog to csproj:
<Content Include="NLog.config">
<SubType>Designer</SubType>
</Content>
<None Include="NLog.aws-prod.config">
<DependentUpon>NLog.config</DependentUpon>
</None>
<None Include="NLog.aws-test.config">
<DependentUpon>NLog.config</DependentUpon>
</None>
but this doesn't copy the transformed NLog.config to the package directory (or when deploying to AWS). The original NLog.config is copied and a copy in the /bin directory as well.
SlowCheetah seems to do what I want. I've tried it and I've made changes to my csproj to add:
<TransformOnBuild>true</TransformOnBuild>
and
<IsTransformFile>True</IsTransformFile>
so the final change looks like this:
<Content Include="NLog.config">
<TransformOnBuild>true</TransformOnBuild>
<SubType>Designer</SubType>
</Content>
<None Include="NLog.aws-prod.config">
<DependentUpon>NLog.config</DependentUpon>
<IsTransformFile>True</IsTransformFile>
<SubType>Designer</SubType>
</None>
<None Include="NLog.aws-test.config">
<DependentUpon>NLog.config</DependentUpon>
<IsTransformFile>True</IsTransformFile>
</None>
That's it and NLog.config is transformed!! This target below wasn't needed:
<Target Name="BeforeBuild" Condition="exists('NLog.$(Configuration).config')">
<Message Text="Tranforming NLog..."/>
<TransformXml Source="NLog.config" Transform="NLog.$(Configuration).config" Destination="$(OutputPath)\NLog.config" />
</Target>

ASP.NET - Copying extra files on publish not working recursively

I have a web application project that I want to publish to a web server. There is a folder of files that are not included in the project, but need to be copied when it is published. I found a few posts on how to do this copying with MSBuild, but I cannot get it to copy all files/folders recursively in the main folder I want to copy.
The folder I want to copy is (proj)/Scripts. (This directory is excluded from the application project because I have all my JavaScript code in a separate project in the same solution, and this folder is copied from the JS project's output folder after it performs minification and other build tasks.)
Here is the section I have added to my *.csproj file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="Scripts\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>
<!-- whitespace and new line added for question readability -->
Scripts\%(RecursiveDir)%(Filename)%(Extension)
</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
This will copy any files in the top level of the /Scripts folder, but nothing in its subfolders.
How do I make it recursive?
Fixed my own problem:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="Scripts\**\*.*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Scripts\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<_CustomFiles Include="Scripts\*" /> had to be changed to
<_CustomFiles Include="Scripts\**\*.*" />
This worked for me:
<ItemGroup>
<Content Include="YourTargetDir\**\*.*">
<Link>YourTargetDir\%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

Previewing before publishing to Azure causes files to be deleted from the deployment location

I have a nuget package that contains an build target file that add files when the project is published to Azure.
I've gotten this to work, but if I press the "Start Preview" button in the publish dialog before I press publish, the nuget-package-files are not published and if they exist on the server they are deleted.
This is the content of the build target file
<ItemGroup>
<LisaFrontendFiles Include="$(MSBuildThisFileDirectory)..\Web\**\*" />
<NativeBinaries Include="$(MSBuildThisFileDirectory)..\lib\native\*" />
</ItemGroup>
<Target Name="LisaFrontendPublishTarget" BeforeTargets="CopyAllFilesToSingleFolderForPackage">
<ItemGroup>
<FilesForPackagingFromProject Include="%(LisaFrontendFiles.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
<ItemGroup>
<FilesForPackagingFromProject Include="%(NativeBinaries.Identity)">
<DestinationRelativePath>bin/%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
LisaFrontendPublishTarget;
$(CopyAllFilesToSingleFolderForMsdeployDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>

Resources