Remove folder from MSBuild - c#

I'm trying to remove a folder (well, actually I thought it was easier to remove the files inside it) from a build using MSBuild scripts.
I thought the way is removing them from the copy task itself, but what I was thinking it was going to see quite straightforward it's not working (I'm sure because I don't have much idea of this stuff, just read documentation yesterday and today). Here is how I'm trying to remove the folder (or the files inside it) ..App_Data/Email Templates with this space (does the space something to do?).
<ItemGroup>
<SourceRootFiles Include="$(BuildFolder)/**/*.*" Exclude="$(BuildFolder)/**/App_Data/Email Templates/*.*">
</SourceRootFiles>
</ItemGroup>
<Target Name="PrepareBuild" DependsOnTargets="CleanUp">
<Message Text="Preparing the build directory : $(LocalBuild)"></Message>
<MakeDir Directories="$(LocalBuild)" />
<Copy SourceFiles="#(SourceRootFiles)" DestinationFolder="$(LocalBuild)\%(RecursiveDir)">
</Copy>
<Exec Command="FOR /r "$(LocalBuild)" %%f IN (.svn) DO RD /s /q "%%f"" IgnoreExitCode="true" />
</Target>
<Target Name="Build" DependsOnTargets="PrepareBuild">
<MSBuild Projects="$(LocalBuild)\Getting.sln" />
</Target>
Update.
Jenkins is raising this error
:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error : Copying file App_Data\Email Templates\BuyerRegistrationComplete.htm to obj\Latest\Package\PackageTmp\App_Data\Email Templates\BuyerRegistrationComplete.htm failed. Could not find a part of the path 'App_Data\Email Templates\BuyerRegistrationComplete.htm'. [C:\Builds\Getting\Latest\Build\Web\UI\UI.csproj]
Dont' really know if it's exluding it or not

On githup is a project named MsBuildTasks that contains all kind of custom-actions that you can easily integrate in your project
https://github.com/loresoft/msbuildtasks
From your update tells a "new" story.
In your project-file you reference files in the App_Data folder which WebDeployment wants to copy to deployment. Removing App_Data results in missing files and thus failure.
Either move those files to another location in your project or remove the references to those files.
My suggestion would be to make a separate folder for the templates, App_Data has a different purpose.

Related

MSBuild copy dlls to bin folder, not following the path

I am using csproj file to bundle Chrome windows edition into our ASP.NET Core app. I place all the needed files into $(ProjectDir)\chrome-win and use below XML to copy the files in csproj
<None Update="chrome-win\**" CopyToPublishDirectory="Always" CopyToOutputDirectory="PreserveNewest" LinkBase="chrome-win\" />
What is strange is that when I publish the project using the built in folder publish profile, all the *.dll files gets copied to bin\chrome-win\ and other files are in chrome-win\. This is so frustrating, how can I tell stupid MSBuild / Visual Studio to not to do this? When I build it, the behavior is even stranger, the *.dll files gets copied twice, once to chrome-win folder, also gets copied to bin folder.
I am using the latest VS 2019 and MSBuild
I believe you would want to use the $(BaseOutputPath) property for your copy so that everything writes into the same folder. So it would look like this.
<None Update="chrome-win\**" CopyToPublishDirectory="Always" CopyToOutputDirectory="PreserveNewest" LinkBase="$(BaseOutputPath)\chrome-win\" />
EDIT1:
If you want all the contents of the bin folder moved to \bin\chrome-win\ you could use the CopyTask
<Copy SourceFiles="$(BaseOutputPath)\*" DestinationFiles="$(BaseOutputPath)\" AfterTargets="AfterBuild" />
You might need to tweak this a bit but it should do what you need.

How can I exclude a file, added by a referenced Nuget package, from my build output? [duplicate]

I have a Visual Studio 2008 C#/.NET 3.5 project with a post build task to ZIP the contents. However I'm finding that I'm also getting the referenced assemblies' .pdb (debug) and .xml (documentation) files in my output directory (and ZIP).
For example, if MyProject.csproj references YourAssembly.dll and there are YourAssembly.xml and YourAssembly.pdb files in the same directory as the DLL they will show up in my output directory (and ZIP).
I can exclude *.pdb when ZIP'ing but I cannot blanket exclude the *.xml files as I have deployment files with the same extension.
Is there a way to prevent the project from copying referenced assembly PDB and XML files?
I wanted to be able to add and remove referenced assemblies in my primary application while avoiding the the need to maintain which files I needed to delete or exclude.
I dug through Microsoft.Common.targets looking for something that would work and found the AllowedReferenceRelatedFileExtensions property. It defaults to .pdb; .xml so I explicitly defined it in my project file. The catch is that you need something (whitespace is not sufficient) otherwise it will still use the default.
<Project ...>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<AllowedReferenceRelatedFileExtensions>
<!-- Prevent default XML and PDB files copied to output in RELEASE.
Only *.allowedextension files will be included, which doesn't exist in my case.
-->
.allowedextension
</AllowedReferenceRelatedFileExtensions>
</PropertyGroup>
You can also specify this via the command line:
MsBuild.exe build.file /p:AllowedReferenceRelatedFileExtensions=none
You can add a Post Build event command similar to del "$(TargetDir)YourAssembly*.xml", "$(TargetDir)YourAssembly*.pdb"
top 2 answers didn't work for me. I found a solution in this link which worked for me. http://kitsula.com/Article/How-to-exclude-xml-doc-files-from-msbuild.
Just in case, the above link is not working:
Unload project in Solution Explorer
Right click the project and click 'edit *.csproj'
Add next lines in the PropertyGroup section of each environment.
Reload and rebuild project.
<AllowedReferenceRelatedFileExtensions>
*.pdb;
*.xml
</AllowedReferenceRelatedFileExtensions>
This is a rather old question, but since there is no answer about how to turn off generating PDB and XML files via UI, i figured that it should be here for completeness.
In Visual Studio 2013: in project properties, under compile tab, uncheck "Generate XML documentation file", then click on "Advanced Compile Options" below that and change "Generate debug info" to "None", and that will do the trick.
I didn't have much luck with the other answers, I finally figured out how to do this in my implementation by using the built in "Delete" command, apparently there is a specific way you need to implement wildcards, it's bit nuanced, here's everything you need to be put into your "CSPROJ" (TargetDir is a built in variable, included automatically) under the "Project" tag:
<Target Name="RemoveFilesAfterBuild">
<ItemGroup>
<XMLFilesToDelete Include="$(TargetDir)\*.xml"/>
<PDBFilesToDelete Include="$(TargetDir)\*.pdb"/>
</ItemGroup>
<Delete Files="#(XMLFilesToDelete)" />
<Delete Files="#(PDBFilesToDelete)" />
</Target>
I've also had trouble with various language specific folders being generated, if you have that issue too, you can also remove unused language specific folders too. I've chosen to only trigger this under the build type "Release":
<ItemGroup>
<FluentValidationExcludedCultures Include="be;cs;cs-CZ;da;de;es;fa;fi;fr;ja;it;ko;mk;nl;pl;pt;ru;sv;tr;uk;zh-CN;zh-CHS;zh-CHT">
<InProject>false</InProject>
</FluentValidationExcludedCultures>
</ItemGroup>
<Target Name="RemoveTranslationsAfterBuild" AfterTargets="AfterBuild" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<RemoveDir Directories="#(FluentValidationExcludedCultures->'$(OutputPath)%(Filename)')" />
<ItemGroup>
<XMLFilesToDelete Include="$(TargetDir)\*.xml"/>
<PDBFilesToDelete Include="$(TargetDir)\*.pdb"/>
</ItemGroup>
<Delete Files="#(XMLFilesToDelete)" />
<Delete Files="#(PDBFilesToDelete)" />
</Target>
My answer might be trivial now but I'd like to share the BAT script I use to delete the xml files if there's a corresponding dll for it. It's useful if you just want to cleanup the output folder and has other xml files that don't want to remove.
SETLOCAL EnableDelayedExpansion
SET targetDir=%1
ECHO Deleting unnecessary XML files for dlls
FOR %%F IN (%targetDir%*.xml) DO (
SET xmlPath=%%~fF
SET dllPath=!xmlPath:.xml=.dll!
IF EXIST "!dllPath!" (
ECHO Deleting "!xmlPath!"
DEL "!xmlPath!"
)
)
Usage:
Cleanup.bat c:\my-output-folder\
It took me an hour to finish this simple work (thanks to the "delayed expansion" stuff) with all type of searching here and there. Hope it helps other BAT newbies like me.
If you only want to exclude the XML files (for say a debug release) you can do something like this:
<AllowedReferenceRelatedFileExtensions>
<!-- Prevent default XML from debug release -->
*.xml
</AllowedReferenceRelatedFileExtensions>
Basically, each extension (delimited by a semi-colon) listed will be excluded.

How to copy Content linked files to project directory without causing duplicates

I am trying to reference some javascript files in my project that are coming from a nuget package. So i added these files as a Content Link reference.
<Content Include="$(NuGetPath_jQuery)\Content\Scripts\**\*.*">
<Link>Scripts\%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
But that I can F5 debug the web project, I need these files to be a part of the project folder structure. I am also using these files in a ScriptBundle so the physical directory structure needs to be present for locally debugging. As a result, I ended up adding the following build ttask that copies the content linked files as per Matt Perdeck's blog which is referenced in a lot of other threads around content linking as per below.
<Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
<Copy SourceFiles="%(Content.Identity)"
DestinationFiles="%(Content.Link)"
SkipUnchangedFiles='true'
OverwriteReadOnlyFiles='true'
Condition="'%(Content.Link)' != ''" />
</Target>
Now VS is happy while F5 debugging. But complains on loading the project the next time about not being able to add the content links because the files already exist. Which were copied in the previous build. Am I missing some secret sauce to tell VS to ignore these warnings? I noticed that msbuild does not throw any such warning. It is only VS that is complaining. I see warnin like below :
Warning The file 'C:\Users\pkorhale.nuget\packages\jquery\3.3.1\Content\Scripts\jquery-3.3.1.slim.min.js' could not be added to the project. Cannot add a link to the file jquery-3.3.1.slim.min.js. There is already a file of the same name in this folder.
Turned out, that I needed to turn off the visibility for this content. Anyways the file gets copied over physically so we end up seeing it in the solution explorer after the first build. Which was good enough for me.
<Content Include="$(NuGetPath_jQuery)\Content\Scripts\**\*.*">
<Link>Scripts\%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>

c# copying files to bin directory

I'm able to have files put into the bin directory using the properties "copy if newer".
The problem I have is that I require a large number of dll files to be put along side my application. This means that my project becomes littered with a large number of files.
I'd like to put my files into an assets folder in my solution but have the files present in the bin directory on build. I have tried using post build events but I keep getting windows error codes (even when it's successful).
Is there an alternative way to have the external dlls accessible to my application?
If you unload the project file you can edit the .csproj file.
Near the end you'll find:
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
-->
Lets modify that.
First define which Items the AfterBuild task is going to copy. Notice that you only have to make sure these files exist on your disk in a folder (you say it is called assets) and are under source control. You don't need to include any of those files in your solution or project.
<ItemGroup>
<!-- Include relative to this project file, so ..\assets would bring you to the solution folder
Take all files in the assets folder and subfolders, except *.txt files
-->
<Asset Include="assets\**" Exclude="*.txt">
</Asset>
<!-- take all *.txt files -->
<TextAsset Include="assets\**\*.txt">
<!-- meta data -->
<SubPath>TextFiles</SubPath>
</TextAsset>
</ItemGroup>
Now you'll have two Item collection, one called Asset and one called TextAsset. Those items can be consumed in build Tasks. We are going to use the Copy task. I've commented the build script to explain what happens.
<!-- this does what the name suggests-->
<Target Name="AfterBuild">
<!-- log -->
<Message Importance="high" Text="Start Copying assets"/>
<!-- copy Asset files to one folder (flattens) -->
<Copy SourceFiles="#(Asset)"
DestinationFolder="$(OutputPath)" />
<!-- copy TextAsset files to a subpath, keep folder structure-->
<Copy SourceFiles="#(TextAsset)"
DestinationFiles="#(TextAsset->'$(OutputPath)%(SubPath)\%(RecursiveDir)%(Filename)%(Extension)')" />
<!-- done logging -->
<Message Importance="high" Text="Copied assets"/>
</Target>
Notice that I used the property $(OutputPath) which is one of the well known properties. A similar list exists for item meta data.
The changes will not affect the operation of visual studio. Your changes will be preserved when adding or removing regular project items and/or project settings. As you'll keep this file in source control, also on your buildserver the same targets will be run, doing the same copy.
I prefer to test these build targets from the commandline, specifying only the target I'm interested in, like so:
msbuild Application2.csproj /t:AfterBuild
That gives you a much quicker round-trip time instead of doing a full build.

How to include dynamically generated files in Visual Studio's publish profile

Our build automatically bundles javascript/css files together, and adds a checksum to the name of the file for easy verification. Because these are auto-generated and the names change, I can't include them into the solution. I've tried looking through the msdn links, but I can't find a full schema for all the possible tags.
Stuff I've found but haven't been able to make sense of:
How to Edit deployment settings in Publish Profile
I've also seen this answer on SO, but I haven't been able to make it work, it tries to put it in the obj folder, instead of the publish folder, and again, I can't find the schema to try and figure out how to redirect it.
Ideally, the final goal is to have the publish profile copy these files that sit under the bundles folder in the project to the bundles folder in the publish directory as specified in the PublishProfile.pubxml file.
Thank you for any help!
I ended up finding someone with a similar issue, who helped me understand what I needed to change in the linked SO answer
I ended up with the following structure, which grabs all css and js files from the root of the project (it looks like you can just invent those JSFile and CSSFile tags, they're just names to be used later), and then sending them to the DestinationRelativePath tag, which needs that %(Filename)%(Extension) bit (otherwise it just tries to create a file called bundles). JSFile.Identity seems to give a list of files.
This is what I ended up with. Notice that CSS has the RecursiveDir part, but it didn't actually do anything, and both local publish and teamcity published everything correctly.
<PropertyGroup>
<CollectFilesFromContentDependsOn>
AddFilesToDeploy;
$(CollectFilesFromContentDependsOn);
</CollectFilesFromContentDependsOn>
</PropertyGroup>
<!--Add files to deploy -->
<Target Name="AddFilesToDeploy">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="CurrentAssembly" />
</GetAssemblyIdentity>
<ItemGroup>
<JsFile Include="bundles\*.js" />
<CssFile Include="bundles\*.css" />
<FilesForPackagingFromProject Include="%(JsFile.Identity)">
<DestinationRelativePath>bundles\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="%(CssFile.Identity)">
<DestinationRelativePath>bundles\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>

Categories