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

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>

Related

Including a custom file in your build/publish for a .net core application

How do I include a custom file that is in the root of my project dir to be put into my build/publish folder?
If its a .json file it seems to come through automatically (probably because of .NET config being json)
I have a custom config file that is text based with a .txt extension.
I've tried:
<ItemGroup>
<DotnetPublishFiles Include="customfile.txt"></DotnetPublishFiles>
</ItemGroup>
And
<ItemGroup>
<Content Include="./*.txt" />
</ItemGroup>
As well as
<ItemGroup>
<Content Include="customfile.txt" />
</ItemGroup>
Also:
<_CustomFiles Include="$(MSBuildProjectDirectory)/customfile.txt" />
<DotNetPublishFiles Include="#(_CustomFiles)">
</DotNetPublishFiles>
</ItemGroup>
Nothing seems to work...
I'm using Visual Studio Code and .NET Core 3.1.
Any ideas?
<ItemGroup>
<None Update="customfile.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<ItemGroup>
JSON (as well as other suitable) files are treated the same way by SDK style projects, so for your own custom files you need to ask MSBuild explicitly.
For publishing there is another tag: CopyToPublishDirectory
<ItemGroup>
<None Update="customfile.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
<ItemGroup>

Include folder not referenced by project?

I'm trying to figure out how to upload a folder that i do not want to reference in the project file. The folder "build" is and output step that is generated from webpack. I've found other threads with the same problem and this is what i've tried (added to the end of my pubxml file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\build\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>build\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
which did not work
Try "CopyAllFilesToSingleFolderForMSDeployDependsOn" instead of "CopyAllFilesToSingleFolderForPackageDependsOn".
<PropertyGroup>
<CopyAllFilesToSingleFolderForMSDeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForMSDeployDependsOn);
</CopyAllFilesToSingleFolderForMSDeployDependsOn>
</PropertyGroup>
Based on my review of the latest MSDeployAddFilesOutsideOfProject.wpp.targets file (distributed with VS2015), "ForPackage" may be deprecated. The target is still there but I can't find where its referenced.
Update - Wrote a quick blog post with more details:
http://www.dotnetcatch.com/2016/07/20/include-extra-files-in-webdeploy-package/

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>

MSbuild batching -- recursive folder copy to multiple destination folders

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>

Clean/Rebuild Solution Before Publishing To Azure

I have a solution which include loosely coupled projects with a ASP.Net MVC application. I have set the output of all projects to 'MvcProject\bin' folder. So, I need to Clean/Rebuild the solution before I will be able to run my web application. The problem is that when I publish this to Azure or Local system then it will not include all the project dlls(and its dependent dlls, it will only include MvcProject and its dependent dlls). Is there is any way to tell the VS(or msbuild) to clean/rebuild the solution and include all the related project dlls which output is set to 'MvcProject\bin'
This is what I did. First of all edited all my class-library projects csproj file OutPath to,
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
..................................
<OutputPath>bin\Debug\</OutputPath>
..................................
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
..................................
<OutputPath>bin\Release\</OutputPath>
..................................
Next add this to my MVC application csproj file bottom(before </Project>),
<Target Name="AfterBuild">
<ItemGroup>
<_CustomFiles Include="..\Project1\bin\$(Configuration)\**\*;..\Project2\bin\$(Configuration)\**\*" />
................................................................
</ItemGroup>
<Copy SourceFiles="#(_CustomFiles)" DestinationFiles="#(_CustomFiles->'bin\%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
</Target>
Finally add this to my Azure.pubxml(you can find it in Properties/PublishProfiles) file bottom(before </Project>),
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\Project1\bin\$(Configuration)\**\*;..\Project2\bin\$(Configuration)\**\*" />
................................................................
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>

Resources