I am trying to copy binaries created by my build to a certain folder using the MSBuild Copy task. Unfortuately, the process fails silently. No error message is issued and no files are copied.
Here is the relevant part of my .csproj file:
<Target Name="CopyFilesForModule" AfterTargets="AfterBuild">
<CreateItem Include="bin\**\*.*" Exclude="bin\**\*.pdb;bin\**\*.xml">
<Output TaskParameter="Include" ItemName="MySourceFiles" />
</CreateItem>
<Copy SourceFiles="$(MySourceFiles)" DestinationFolder="Areas\KoobooModule7\bin">
<Output
TaskParameter="CopiedFiles"
ItemName="Changed" />
</Copy>
<Message Text="sourcefiles: #(MySourceFiles)" />
<Message Text="changed:#(Changed)" Importance="high" />
</Target>
As you can see I have already added messages for debug purposes. I call msbuild using the following command line:
"c:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe" /t:rebuild /verbosity:d
iag KoobooModule7.csproj > buildlog.txt
Here is the relevant excerpt from my build log:
Target "CopyFilesForModule: (TargetId:75)" in project "C:\Users\chris\Documents\Visual Studio 2013\Projects\KoobooModule7\KoobooModule7\KoobooModule7.csproj" (target "Build" depends on it):
Task "CreateItem" (TaskId:43)
Task Parameter:Include=bin\**\*.* (TaskId:43)
Task Parameter:
Exclude=
bin\**\*.pdb
bin\**\*.xml (TaskId:43)
Done executing task "CreateItem". (TaskId:43)
Task "Copy" (TaskId:44)
Task Parameter:DestinationFolder=Areas\KoobooModule7\bin (TaskId:44)
Done executing task "Copy". (TaskId:44)
Task "Message" (TaskId:45)
Task Parameter:Text=sourcefiles: bin\CookComputing.XmlRpcV2.dll;bin\DiffPlex.dll;bin\dotless.Core.dll;bin\DotNetOpenAuth.AspNet.dll;bin\DotNetOpenAuth.Core.dll;bin\DotNetOpenAuth.OAuth.Consumer.dll;bin\DotNetOpenAuth.OAuth.dll;bin\DotNetOpenAuth.OpenId.dll;bin\DotNetOpenAuth.OpenId.RelyingParty.dll;bin\HtmlAgilityPack.dll;bin\Ionic.Zip.Reduced.dll;bin\Kooboo.CMS.Account.dll;bin\Kooboo.CMS.Caching.dll;bin\Kooboo.CMS.Common.dll;bin\Kooboo.CMS.Common.Runtime.Dependency.Ninject.dll;bin\Kooboo.CMS.Content.dll;bin\Kooboo.CMS.Form.dll;bin\Kooboo.CMS.Membership.dll;bin\Kooboo.CMS.Search.dll;bin\Kooboo.CMS.Sites.dll;bin\Kooboo.CMS.Sites.TemplateEngines.Razor.dll;bin\Kooboo.CMS.Web.dll;bin\Kooboo.dll;bin\KoobooModule7.dll;bin\KoobooModule7.dll.config;bin\Lucene.Net.Contrib.Highlighter.dll;bin\Lucene.Net.dll;bin\Microsoft.Web.Infrastructure.dll;bin\Mono.Math.dll;bin\Newtonsoft.Json.dll;bin\Ninject.dll;bin\NuGet.Core.dll;bin\Org.Mentalis.Security.Cryptography.dll;bin\System.Net.Http.dll;bin\System.Web.Helpers.dll;bin\System.Web.Mvc.dll;bin\System.Web.Razor.dll;bin\System.Web.WebPages.Administration.dll;bin\System.Web.WebPages.Deployment.dll;bin\System.Web.WebPages.dll;bin\System.Web.WebPages.Razor.dll (TaskId:45)
sourcefiles: bin\CookComputing.XmlRpcV2.dll;bin\DiffPlex.dll;bin\dotless.Core.dll;bin\DotNetOpenAuth.AspNet.dll;bin\DotNetOpenAuth.Core.dll;bin\DotNetOpenAuth.OAuth.Consumer.dll;bin\DotNetOpenAuth.OAuth.dll;bin\DotNetOpenAuth.OpenId.dll;bin\DotNetOpenAuth.OpenId.RelyingParty.dll;bin\HtmlAgilityPack.dll;bin\Ionic.Zip.Reduced.dll;bin\Kooboo.CMS.Account.dll;bin\Kooboo.CMS.Caching.dll;bin\Kooboo.CMS.Common.dll;bin\Kooboo.CMS.Common.Runtime.Dependency.Ninject.dll;bin\Kooboo.CMS.Content.dll;bin\Kooboo.CMS.Form.dll;bin\Kooboo.CMS.Membership.dll;bin\Kooboo.CMS.Search.dll;bin\Kooboo.CMS.Sites.dll;bin\Kooboo.CMS.Sites.TemplateEngines.Razor.dll;bin\Kooboo.CMS.Web.dll;bin\Kooboo.dll;bin\KoobooModule7.dll;bin\KoobooModule7.dll.config;bin\Lucene.Net.Contrib.Highlighter.dll;bin\Lucene.Net.dll;bin\Microsoft.Web.Infrastructure.dll;bin\Mono.Math.dll;bin\Newtonsoft.Json.dll;bin\Ninject.dll;bin\NuGet.Core.dll;bin\Org.Mentalis.Security.Cryptography.dll;bin\System.Net.Http.dll;bin\System.Web.Helpers.dll;bin\System.Web.Mvc.dll;bin\System.Web.Razor.dll;bin\System.Web.WebPages.Administration.dll;bin\System.Web.WebPages.Deployment.dll;bin\System.Web.WebPages.dll;bin\System.Web.WebPages.Razor.dll (TaskId:45)
Done executing task "Message". (TaskId:45)
Task "Message" (TaskId:46)
Task Parameter:Text=changed: (TaskId:46)
Task Parameter:Importance=high (TaskId:46)
changed: (TaskId:46)
Done executing task "Message". (TaskId:46)
Done building target "CopyFilesForModule" in project "KoobooModule7.csproj".: (TargetId:75)
As you can see, the files to copy have been identified correctly while the copied files are empty. How can I find out why the copy process fails?
You're not referencing the MySourceFiles item in the copy task, but the MySourceFiles property.
<Copy SourceFiles="$(MySourceFiles)" DestinationFolder="Areas\KoobooModule7\bin">
Should be
<Copy SourceFiles="#(MySourceFiles)" DestinationFolder="Areas\KoobooModule7\bin">
Related
I have a C# project (vs2013) and for this project, i want to do always a clean solution before the build. Now i can (again and again) choose clean project before building, but this should be possible using a Target tag in the .csproj file. I started looking on the internet and came up with a solution that did not work:
<Target Name="Clean"
BeforeTargets="Build">
<Message Text="### Start Clean before build"
Importance="high" />
<Exec Command="CALL "$(MSBuildBinPath)\msbuild.exe" "$(MSBuildProjectFullPath)" /t:Clean" />
<Message Text="### Finished Clean before build"
Importance="high" />
</Target>
But this results in an infinite loop, starting msbuild over and over again.
You've defined the target recursively. Don't name it "Clean", name it "PreBuildClean" or something similar.
Also you don't have to call out to msbuild externally using Exec. You can use the CallTarget task to invoke a target directly.
<Target Name="PreBuildClean"
BeforeTargets="Build">
<Message Text="### Start Clean before build"
Importance="high" />
<CallTarget Targets="Clean" / >
<Message Text="### Finished Clean before build"
Importance="high" />
</Target>
The Rebuild target is just Clean followed by Build, so I'm not sure why you'd need this, unless it is only for one specific project in the solution.
I tried to automate update, build and Publish using cruise Control, SVN and Ms build . Take update from svn repository and build is working fine but publishing time, in the bin folder only the project dlls are coming , but other dlls like 'system.web' , 'Newtonsoft.Json' , etc and many more dlls are not updating. My 'ccnet.config' file is given :
<cruisecontrol xmlns:cb="urn:ccnet.config.builder" xmlns="http://thoughtworks.org/ccnet/1/8">
<project name="MyProjectBuild" queue="Q1" queuepriority="1">
<sourcecontrol type="svn">
<trunkurl>https://ip/svn//trunk/CruiseControlTest</trunkurl>
<workingdirectory>F:\CruiseControlPOC\src</workingdirectory>
<username>username</username>
<password>password</password>
</sourcecontrol>
<tasks>
<msbuild>
<executable>C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
<workingdirectory>F:\CruiseControlPOC\BuildScript\</workingdirectory>
<projectfile>Build.xml</projectfile>
</msbuild>
</tasks>
</project>
</cruisecontrol>
My 'Build.xml' file which 'ccnet.config' refer is given here:
<target name="Run">
<calltarget targets="Compile" />
<calltarget targets="DoPublish" />
</target>
<target name="Compile">
<msbuild projects="..\src\HelloWorld\HelloWorld.sln" />
</target>
<target name="DoPublish">
<msbuild projects="..\src\HelloWorld\HelloWorld\HelloWorld.csproj" targets="_CopyWebApplication;_BuiltWebOutputGroupOutput" properties="OutDir=..\Output\;WebProjectOutputDir=..\..\..\Publish\HelloWorldSite\;"> </msbuild>
<copy sourcefiles="..\Output\" destinationfolder="..\Publish\HelloWorldSite\bin\"> </copy>
</target>
Can anyone tell how to use copy command so as to copy build dlls from Output folder to Publish/bin folder , or is there any other to Publish files using MsBuild and Cruise Control. Thanks
You could add another task after your MSBuild task in the ccnet.config to call a Power Shell script after the build like so:
<exec>
<executable>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</executable>
<baseDirectory>D:\Tools</baseDirectory>
<buildArgs>-File "D:\Tools\ProgramNamePostBuildTasks.ps1"</buildArgs>
<buildTimeoutSeconds>600</buildTimeoutSeconds>
</exec>
Then in your powershell script you could use xcopy to copy files where ever you want. If you are going to copy the files to a server, you will need to map a connection to the server first. But here is a simple example of how the powershell script will look:
del "D:\Binfolder\*.*"
xcopy "D:\OutputDirectory\ProgramX.dll" "D:\BinFolder\"
My team has a large solution (~500 csproj's). We use VS2012, and build using TFS Build, which uses MSBuild 4. Currently we build serially, but we want to build in parallel (using msbuild /maxcpucount:4). However, when I try it on my 4-proc machine, I get a weird failure:
11:2>CSC : fatal error CS0042: Unexpected error creating debug information file 'C:\Common\obj\Debug\Common.PDB' -- 'C:\Common\obj\Debug\Common.pdb: The process cannot access the file because it is being used by another process. [C:\Common\Common.csproj]
Looking at the log, 2 msbuild nodes were trying to build that same csproj, and thus colliding on writing some output:
10>Project "C:\Utils\Utils.csproj" (10) is building "C:\Common\Common.csproj" (11) on node 4 (default targets).
46:2>Project "C:\Objects\Objects.csproj" (46:2) is building "C:\Common\Common.csproj" (11:2) on node 1 (default targets).
Why would MSBuild try to build the same project twice?
Cause: Someone was calling <MSBuild Projects="Common.csproj" Properties="..." />. Then, MSBuild thinks that it should build Common.csproj again with those different properties, and it happened to occur at the same time with the regular compilation of Common.csproj.
Fix: Call <MSBuild ... /> without those unneeded properties.
Test:
Common.targets
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<Message Importance="high" Text="Build in $(MSBuildThisFile)" />
</Target>
<Target Name="After" DependsOnTargets="Build">
<Message Importance="high" Text="After in $(MSBuildThisFile)" />
</Target>
</Project>
Other.targets
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<Message Importance="high" Text="Build in $(MSBuildThisFile)" />
<MSBuild Projects="common.targets" Targets="Build" /> <!-- regular builds -->
<MSBuild Projects="common.targets" <!-- custom invocation with properties -->
Targets="After"
Properties="myprop=myvalue"
/>
</Target>
</Project>
Run:
> msbuild other.targets /clp:verbosity=minimal
Build in other.targets
Build in common.targets
Build in common.targets <<<< Common.targets Build is invoked again
After in common.targets
And indeed, removing Properties="myprop=myvalue" solves the issue.
I found someone had added two project references (from the same project) and that apparently caused msbuild to build twice also.. something to watch out for
I want to run an MSBuild Task (which signs an executable/dll) but only when the output exe/dll has changed. If none of the source files have changed causing a recompile of the exe/dll then I don't want the task to run.
Despite spending several hours trying different things out I cannot work out how to get my target task to only run if the project has been compiled where the output files have changed (in other words the CoreCompile target was not skipped I think).
You can just do this:
<PropertyGroup>
<TargetsTriggeredByCompilation>DoStuffWithNewlyCompiledAssembly</TargetsTriggeredByCompilation>
</PropertyGroup>
This works because someone smart at Microsoft added the following line at the end of the CoreCompile target in Microsoft.[CSharp|VisualBasic][.Core].targets (the file name depends on the language and MSBuild/Visual Studio version).
<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''"/>
So if you specify a target name in the TargetsTriggeredByCompilation property, your target will run if CoreCompile runs-- and your target will not run if CoreCompile is skipped (e.g. because the output assembly is already up-to-date with respect to the code).
Should be the same as this answer, using the TargetOutputs parameter::
<MSBuild Projects="File.sln" >
<Output TaskParameter="TargetOutputs" ItemName="AssembliesBuiltByChildProjects" />
</MSBuild>
<Message Text="Assemblies built: #(AssembliesBuiltByChildProjects)" /> <!-- just for debug -->
<CallTarget Targets="SignExe" Condition="'#(AssembliesBuiltByChildProjects)'!=''" />
I'm creating a custom ITask for MSBuild which uploads the output files of my build. I'm using a web deployment project to publish my app and hooking in to the AfterBuild target to do my custom work.
If I add a file to my web application, the first time I do a build, my custom task is not recognizing the recently added file. In order for that file to show up in my array of ITaskItems, I have to first do a build with my 'AfterBuild' target removed and then start the build again with my 'AfterBuild' target in place.
Here is what my build file looks like:
<ItemGroup>
<PublishContent Include="$(OutputPath)\**" />
</ItemGroup>
<Target Name="AfterBuild">
<UploadTask FilesToPublish="#(PublishContent)" />
</Target>
The list in #(PublishContent) seems to be initialized at the beginning of the build instead of reflecting any changes that might have taken place by the build process itself.
Any ideas?
Thanks
Your ItemGroup is going to get evaluated when the project file first loads (when you first open Visual Studio or you 'unload' and 'reload' the project in Solution Explorer).
What you probably need is to create an ItemGroup as a task in your 'AfterBuild' target. Example:
<CreateItem Include="$(OutputPath)\**">
<Output TaskParameter="Include" ItemName="OutputFiles"/>
</CreateItem>
followed by:
<Target Name="AfterBuild">
<UploadTask FilesToPublish="#(OutputFiles)" />
</Target>