I'm developing a solution containg multiple web projects that share static content like javascript files.
I've done some research and it seems that proper way of handling it is to add shared files as solution items and then add them as links to web projects:
Then web projects should implement copying these files to output directory (I set them to Content beforehand):
<Project Sdk="Microsoft.NET.Sdk.Web">
...
<Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
<Copy SourceFiles="%(Content.Identity)"
DestinationFiles="%(Content.Link)"
OverwriteReadOnlyFiles="true"
ContinueOnError="true"
Condition="'%(Content.Link)' != ''" />
</Target>
</Project>
Unfortunetely it doesn't work. I tried installing the MSBuild.WebApplication.CopyContentLinkedFiles NuGet package, but it didn't help.
I tried setting Copy to output directory property to Always which make them present in the build:
However scripts were still missing after launching the app from VS:
How can I make this work? I'm looking for a simplest solution possible.
Your setup potentially will work for publish scenarios but for development environment it won't - the wwwroot folder from the project root (i.e. WebApp1\wwwroot and WebApp2\wwwroot) is used to serve the static files, so you need to copy the shared file there on build (possibly exclude it from git also for convenience).
Related
Visual Studio creates two files along with the .exe for my project that are required to run the exe: a deps.json and a runtimeconfig.json. A second project in my solution has the first project as a project reference, but those two files aren't being copied to my second project's output directory. How can I tell Visual Studio that it should copy these files into the output directory of the second project, because the referenced project depends on them?
Output directory of my first project:
Foo.exe
Foo.deps.json
Foo.runtimeconfig.json
Output directory of my second project:
Bar.exe
Foo.exe
Should contain deps and runtimeconfig files, but does not
The solution I found is to manually edit my .csproj file to add the following target:
<Target Name="AddRuntimeDependenciesToContent"
Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'"
BeforeTargets="GetCopyToOutputDirectoryItems"
DependsOnTargets="GenerateBuildDependencyFile;
GenerateBuildRuntimeConfigurationFiles">
<ItemGroup>
<ContentWithTargetPath Include="$(ProjectDepsFilePath)"
Condition="'$(GenerateDependencyFile)' == 'true'"
CopyToOutputDirectory="PreserveNewest"
TargetPath="$(ProjectDepsFileName)" />
<ContentWithTargetPath Include="$(ProjectRuntimeConfigFilePath)"
Condition="'$(GenerateRuntimeConfigurationFiles)' == 'true'"
CopyToOutputDirectory="PreserveNewest"
TargetPath="$(ProjectRuntimeConfigFileName)" />
</ItemGroup>
</Target>
This solution came from https://github.com/dotnet/sdk/issues/1675#issuecomment-658779827.
There were other somewhat similar solutions posted in that thread, but this is the only one that worked for me. The others would either not consistently copy the files to my second project, or cause the first project to fail to build due to attempting to access a file that didn't yet exist. The key difference with this one is the inclusion of the correct "BeforeTargets" property (and possibly also "DependsOnTargets"), controlling at which point in the build process the files are included.
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>
I'm developing web service that and later publish it using VS wizard. My service uses external dll that also should be published. How to tell system to publish dll to web services bin folder.
I assume when you publish VS has created *.pubxml file inside your Properties folder, for example I am using VS 2015 for MVC 4.5 and below is my location where my *.pubxml file is found.
You can edit this xml file as explained in ASP.NET Web Deployment using Visual Studio: Deploying Extra Files and add your extra DLLs folder here.
If you add reference to your external dlls and use anything inside the dll, that dll will be automatically copied to the bin folder together with your dll.
In case your dlls are loaded dynamically, you can try adding this to your .csproj file:
<Target Name="AdditionalPublish" AfterTargets="AfterPublish">
<Copy SourceFiles="" DestinationFolder="$(OutputPath)" />
</Target>
Specify SourceFiles with what you want to publish: https://msdn.microsoft.com/en-us/library/3e54c37h.aspx
For example, let's say you want to copy these dlls:
<ItemGroup>
<ExternalFiles Include="lib1.dll;lib2.dll;lib3.dll"/>
</ItemGroup>
<Target Name="AdditionalPublish" AfterTargets="AfterPublish">
<Copy
SourceFiles="#(ExternalFiles)"
DestinationFolder="$(OutputPath)"
/>
</Target>
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.
I run an ASP.NET website solution with a few other projects in it. I've known that MSBuild projects are capable of this, but is it the best way? Are they easy to create? Is nAnt, CruiseControl.NET or any other solution better?
When I build the site (using Web Deployment Projects), can I automate part of the build so that it does not copy certain folders from the project into the Release folder? For instance, I have folders with local search indexes, images and other content part of the folder, but I never need or upload those when deploying the project.
I'm also looking toward this type of solution to automatically increment build and version numbers.
Here's an example of a Web Deployment Project scripting this sort of task in the .wdproj file:
<Target Name="AfterBuild">
<!-- ============================ Script Compression============================ -->
<MakeDir Directories="$(OutputPath)\compressed" />
<Exec Command="java -jar c:\yuicompressor-2.2.5\build\yuicompressor-2.2.5.jar --charset UTF-8 styles.css -o compressed/styles.css" WorkingDirectory="$(OutputPath)" />
<Exec Command="move /Y .\compressed\* .\" WorkingDirectory="$(OutputPath)" />
<RemoveDir Directories="$(OutputPath)\sql" />
<Exec Command="c:\7zip-4.4.2\7za.exe a $(ZipName).zip $(OutputPath)\*" />
</Target>
This would allow you to delete a folder.
(I suspect that if you wanted to not have the folder copy over at all, the solution file would be the place to specify that, though I haven't had to use that.)
MaseBase, you can use Web Deployment Projects to build and package Web Sites. We do that all the time for projects with a web application aspect. After you assign a WDP to a Web Site, you can open up the .wdproj file as plain-text XML file. At the end is a commented section of MSBuild targets that represent the sequence of events that fire during a build process.
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.WebDeployment.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="BeforeMerge">
</Target>
<Target Name="AfterMerge">
</Target>
<Target Name="AfterBuild">
</Target>
-->
You can uncomment the targets you want (e.g. "AfterBuild") and insert the necessary tasks there to carry out your repeated post-build activities.
You can set the Build Action/Copy to Output Directory property on individual files (select the file and hit F4 to open the properties window) to control what happens to them during build, but not for folders. This could probably be automated with a (pre) build task if you don't want to do it manually.
Alternatively, you can exclude these folders from the project (right click and 'exclude from project'); they'll still be there ("show all files" in solution explorer), but they won't be included when building the project.
CruiseControl.NET solves a different problem (continuous integration) ... however, I've had great success with NAnt for specifically what you're asking. There's a learning curve, but once you get proficient you'll wonder how you ever got along w/o it.
In addition to #Fredrik's tip about setting project items to "Copy to Output Directory", you can also specify a post-build action in the project's properties in the Build tab and include CMD commands like copy.exe and move.exe.
We use FinalBuilder to automate a bunch of post build / pre build tasks. There's also a web interface so you can kick off builds (or push websites) by logging in to the web site and clicking a button.
http://www.finalbuilder.com/
Can't you edit the Web Deployment project's MSBuild file for it to do what you want?