Please see the DOS command below:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe WindowsFormsApplication1.csproj /t:Test
The .csproj file looks like this:
<PropertyGroup>
<NUnit3-ToolPath>C:\Development\C#\UnitTests\UnitTests\packages\NUnit.ConsoleRunner.3.6.1\tools</NUnit3-ToolPath>
</PropertyGroup>
<Target Name="Test">
<NUnit3 ToolPath="$(NUnit3-ToolPath)" Assemblies="C:\Development\C#\UnitTests\WindowsFormsApplication1\bin\Debug\UnitTests.dll" OutputXmlFile="test-results.xml" />
</Target>
If I exclude: /t:Test from the DOS command then the build succeeds even if the unit tests fail. How do I ensure the unit tests are run when this command is run:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe WindowsFormsApplication1.csproj
The answer was just to add an AfterTargets attribute as follows:
<Target Name="Test" **AfterTargets="Build">**
<NUnit3 ToolPath="$(NUnit3-ToolPath)" Assemblies="C:\Development\C#\UnitTests\WindowsFormsApplication1\bin\Debug\UnitTests.dll" OutputXmlFile="test-results.xml" /> </Target>
Related
I have the below MSBuild to generate .cs files from my proto files. The build works fine until I do a rebuild where it complains of Source file 'generated-proto-output/Trade.cs# specified multiple times.
How do I delete my .cs files before building/rebuilding everytime?
Error
Severity Code Description Project File Line Suppression State
Warning CS2002 Source file 'generated-proto-output\ErrorTrade.cs' specified multiple times MyComp.Trade.Model C:\dev\workspaces\trade-model-workspace\model\csharp\MyComp.Trade.Model
build snippet in csproj file
<ItemGroup>
<Protobuf Remove="%(RelativePath)generated-proto-output/**/*.cs" />
<Protobuf Include="../../proto/**/*.proto" ProtoRoot="../../proto/" OutputDir="%(RelativePath)generated-proto-output/" GrpcServices="None" />
<Protobuf Update="../../proto/**/*Service.proto" GrpcServices="Both" />
</ItemGroup>
UPDATE - Complete CSProj file (as requested by Lance)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>TradeStore.Model</PackageId>
<ProtoIncludes>.;../../proto</ProtoIncludes>
<OutputType>Library</OutputType>
<TargetFramework>netstandard2.0</TargetFramework>
<Protobuf_NoWarnMissingExpected>true</Protobuf_NoWarnMissingExpected>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
<PackageReference Include="Grpc" Version="1.19.0" />
<PackageReference Include="Grpc.Tools" Version="1.19.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<FilesToDelete Include="%(RelativePath)generated-proto-output/*.cs" />
</ItemGroup>
<Target Name="DeleteSpecificFiles" BeforeTargets="Build">
<Message Text="Specific Files: #(FilesToDelete)"/>
<Message Text ="Beginning to delete specific files before build or rebuild..."/>
<Delete Files="#(FilesToDelete)"/>
</Target>
<ItemGroup>
<Protobuf Include="../../proto/**/*.proto" ProtoRoot="../../proto/" OutputDir="%(RelativePath)generated-proto-output/" GrpcServices="None" />
<Protobuf Update="../../proto/**/*Service.proto" GrpcServices="Both" />
</ItemGroup>
</Project>
Try adding CompileOutputs="false" to the directive. This will suppress the warning and won't require you to delete files before building csharp protobuf build integration
How do I delete my .cs files before building/rebuilding everytime?
Try the following script with BeforeTargets below:
<Project...>
...
<ItemGroup>
<FilesToDelete Include="MyPath/*.cs" />
</ItemGroup>
<Target Name="DeleteSpecificFiles" BeforeTargets="build">
<Message Text="Specific Files: #(FilesToDelete)"/>
<Message Text ="Beginning to delete specific files before build or rebuild..."/>
<Delete Files="#(FilesToDelete)"/>
</Target>
</Project>
In addition:
Not seeing the whole content of your .csproj, so I can't figure out why the build snippet you use can't work. But a message task may help output some message whether the engine finds the files by your given path.
In visual studio, if you go Tools=>Options=>Project and Solutions=>Build and Run to change the build out verbosity to Detailed, you will see detailed output message after every build and rebuild.Ctrl+Fand type the Target name you will find the details about delete process:
Hope it makes some help for your trouble-shooting.
I currently have a solution with a web.api project that I want to deploy to different virtual directories in my local IIS. Currently I am doing the following in the .csproj of the api:
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)' == 'CustomerOne.Debug'">
<CustomerName>CustomerOne</CustomerName>
....
</PropertyGroup>
...
These variables are used extenisvely further on for web.config transforms, copying to different locations, etc., by referencing them like $(CustomerName).
The only place where it does not work is in the definition of the virtual directory, i.e., I'd like to connect the build configuration to the IISUrl below, which you can hardcode:
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
...
<IISUrl>http://localhost/api/something</IISUrl>
...
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
Replacing this by <IISUrl>http://localhost/api/$(CustomerName)</IISUrl> does not work. Ideas?
Replacing this by http://localhost/api/$(CustomerName) does not work. Ideas?
That because Anything inside of a ProjectExtensions element will be ignored by MSBuild.
You can get the detailed info from this document ProjectExtensions Element (MSBuild):
Allows MSBuild project files to contain non-MSBuild information.
Anything inside of a ProjectExtensions element will be ignored by
MSBuild.
That is the reason why the Msbuild variables not work in Project Extensions.
Hope this helps.
You could update the underlying project file. A Target like this in your project file would do it.
<Target Name="AfterBuild">
<PropertyGroup>
<NewUrl>http://localhost/api/$(CustomerName)</NewUrl>
</PropertyGroup>
<Message Text="Updating IISUrl: $(NewUrl) in $(MSBuildProjectFile)" />
<XmlPeek Namespaces="<Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/>" XmlInputPath="$(MSBuildProjectFile)" Query="/msb:Project/msb:ProjectExtensions/msb:VisualStudio/msb:FlavorProperties/msb:WebProjectProperties/msb:IISUrl/text()">
<Output TaskParameter="Result" ItemName="Peeked" />
</XmlPeek>
<Message Text="Current Url: #(Peeked)" />
<!-- Only update the IISUrl if its changed -->
<XmlPoke Condition=" '#(Peeked)'!='$(NewUrl)' " XmlInputPath="$(MSBuildProjectFile)" Namespaces="<Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/>" Query="/msb:Project/msb:ProjectExtensions/msb:VisualStudio/msb:FlavorProperties/msb:WebProjectProperties/msb:IISUrl" Value="$(NewUrl)" />
</Target>
However it does have side affects. Changing the underlying project file means Visual Studio decides it should reload the project.
To use it you cannot go directly into Debug. Instead build, reload the project and then go into debug. If you go directly into Debug (with a compile) it will use the old url.
I created a C# file. Normally we build it using the Visual Studio IDE. But I want to build it using MSBuild.
I have one .bat and .xml file. What exactly I have to do with .xml file to build that .cs file successfully?
My .xml file:
<property environment="env" />
<property name="tools.dir" location="${env.TOOLS_DIR}"/>
<target name="Buildproject" >
<echo message="I am building project"/>
</target>
<target name="runtests" depends="Buildproject" description="This is my first ant target">
<echo message="Running tests"/>
</target>
<target name="publish" depends="runtests">
<echo message="Publish artifact"/>
</target>
My .bat file
SET WORKSPACE=%~dp0 SET TOOLS_DIR=buildtools SET
BUILD_FILE=sample_build.xml #echo off echo WORKSPACE: %WORKSPACE% echo
TOOLS_DIR: %TOOLS_DIR% echo BUILD_FILE: %BUILD_FILE%
%TOOLS_DIR%/apache-ant/bin/ant -Divy.cache.ttl.default=eternal
-buildfile %BUILD_FILE%
Your xml file is not right. It looks like maybe a nant file or some other specification.
Here is your most basic .proj (msbuild definition) file.
Save this (in the same directory as your .sln file) as "MyMsbuildDef.proj"
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapped">
<PropertyGroup>
<!-- Always declare some kind of "base directory" and then work off of that in the majority of cases -->
<WorkingCheckout>.</WorkingCheckout>
</PropertyGroup>
<Target Name="AllTargetsWrapped">
<CallTarget Targets="BuildItUp" />
</Target>
<Target Name="BuildItUp" >
<MSBuild Projects="$(WorkingCheckout)\MySolution_Or_MyProject_File.sln" Targets="Build" Properties="Configuration=$(Configuration)">
<Output TaskParameter="TargetOutputs" ItemName="TargetOutputsItemName"/>
</MSBuild>
<Message Text="BuildItUp completed" />
</Target>
</Project>
Obviously, change "MySolution_Or_MyProject_File.sln" to your .sln name.
Now create a .bat file called "MyMsbuildCallIt.bat" and put this in:
REM set __msBuildDir=%WINDIR%\Microsoft.NET\Framework\v2.0.50727
REM set __msBuildDir=%WINDIR%\Microsoft.NET\Framework\v3.5
set __msBuildDir=%WINDIR%\Microsoft.NET\Framework\v4.0.30319
call "%__msBuildDir%\msbuild.exe" /target:AllTargetsWrapped "MyMsbuildDef.proj" /p:Configuration=Debug;FavoriteFood=Popeyes /l:FileLogger,Microsoft.Build.Engine;logfile=MyMsbuildDef_Debug.log
call "%__msBuildDir%\msbuild.exe" /target:AllTargetsWrapped "MyMsbuildDef.proj" /p:Configuration=Release;FavoriteFood=Popeyes /l:FileLogger,Microsoft.Build.Engine;logfile=MyMsbuildDef_Release.log
set __msBuildDir=
And run the .bat file.
That is your most basic msbuild scenario.
I'm working on an ASP.NET 4 WebAPI project and am including a wpp.targets file. I need to use MSBuild.ExtensionPack.Xml.XmlFile to replace a value in one of my configuration XML files.
The problem is that I don't want to install MSBuild.ExtensionPack on all the machines so I packaged it up with the project. On my local build, the path to the MSBuild.ExtensionPack.dll resolves correctly. On my build machine though, I keep getting this error: The "MSBuild.ExtensionPack.Xml.XmlFile" task could not be loaded from the assembly C:\Program Files (x86)\MSBuild\ExtensionPack\4.0\MSBuild.ExtensionPack.dll.
It seems to be resolving to the default install location of the package.
Here's what's in my wpp.targets file:
<?xml version="1.0" encoding="utf-8"?>
<!-- Sets the assembly which will run the transformation on Web.config (Should be installed on Dev machines) -->
<UsingTask TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
<!-- Get the path to the MSBuild.Extension.Pack -->
<PropertyGroup>
<TPath>$(MSBuildProjectDirectory)\..\packages\MSBuild.Extension.Pack.1.3.0\tools\net40\MSBuild.ExtensionPack.tasks</TPath>
<TPath Condition="Exists('$(MSBuildProjectDirectory)\..\packages\MSBuild.Extension.Pack.1.3.0\tools\net40\MSBuild.ExtensionPack.tasks')">$(MSBuildProjectDirectory)\..\packages\MSBuild.Extension.Pack.1.3.0\tools\net40\MSBuild.ExtensionPack.tasks</TPath>
</PropertyGroup>
<!--Import the MSBuild.Extension.Pack package -->
<Import Project="$(TPath)"/>
<!-- Make sure web.config and transformation files exist -->
<Target Name="ConfigurationTransform" BeforeTargets="BeforeBuild" Condition="Exists('Web.config')" />
<Target Name="ConfigurationTransform" BeforeTargets="BeforeBuild" Condition="Exists('Web.$(Configuration).config')" />
<!-- Make sure web.config will be there even for package/publish -->
<Target Name="CopyWebConfig" BeforeTargets="Build;Rebuild">
<Copy SourceFiles="Web.Base.config"
DestinationFiles="Web.config"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</Target>
<!-- Run Web.Config transformation on a build as well (not just a publish) -->
<Target Name="CustomTransformWebConfigOnBuild" AfterTargets="CopyWebConfig" >
<Message Text="Transforming: Web.$(Configuration).config" Importance="high" />
<TransformXml Source="Web.Base.config"
Transform="Web.$(Configuration).config"
Destination="Web.config" />
</Target>
<!-- Update Web.Config's config attribute -->
<Target Name="UpdateConfigAttribute" AfterTargets="CustomTransformWebConfigOnBuild" Condition="$(Configuration) != 'Release'">
<Message Text="Transforming: Web.config" Importance="high" />
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="UpdateAttribute"
File="Web.config"
XPath="/configuration/appSettings/add[#key='config_url']"
Key="value"
Value="www.randomurl.com"/>
</Target>
When you have more than 1 option for the source location for a helper-dll...I like to do it like with the style below.
Something like this (Obviously, you'll have to put real locations in for "PossibleLocationOne" and "PossibleLocationTwo").
<PropertyGroup>
<MyFoundMSBuildExtensionPackLocation Condition="Exists('..\PossibleLocationOne\MSBuild.ExtensionPack.dll')">..\PossibleLocationOne\MSBuild.ExtensionPack.dll</MyFoundMSBuildExtensionPackLocation>
<MyFoundMSBuildExtensionPackLocation Condition="Exists('..\PossibleLocationTwo\MSBuild.ExtensionPack.dll')">..\PossibleLocationTwo\MSBuild.ExtensionPack.dll</MyFoundMSBuildExtensionPackLocation>
<!--Now check to see if either of the two above resolved , if not , add something to the path so you can at least -->
<MyFoundMSBuildExtensionPackLocation Condition="'$(MyFoundMSBuildExtensionPackLocation)'==''">DID_NOT_FIND_A_PATH_FOR_MSBUILDEXENSIONPACK\MSBuild.ExtensionPack.dll</MyFoundMSBuildExtensionPackLocation>
</PropertyGroup>
<UsingTask AssemblyFile="$(MyFoundMSBuildExtensionPackLocation)" TaskName="TransformXml"/>
Add all options for possible locations..and one extra for "I didn't find a match"....
Then use the "UsingTask".
"UsingTask" is ~~after~~ the MyFoundMSBuildExtensionPackLocation(PropertyGroup).......so the $(MyFoundMSBuildExtensionPackLocation) resolves before the UsingTask is called.
I'm trying to build a project(A) using NANT. The project(A) relies upon another project(B) which is also built with NANT. I want to be able to invoke the build of the dependent project(B) from within the build of project(A). I've tried including the build file of project B in the build file of project A. This creates an error because the two build files contain targets that share the same name.
Is there a way to alias the included build file?
You can do it like this by creating a "parent" buildfile, that uses the "nant" action to call other buildfiles.
<target name="rebuild" depends="" >
<nant target="${target::get-current-target()}">
<buildfiles>
<include name="projectB.build" />
<include name="projectC.build" />
</buildfiles>
</nant>
</target>
I was trying to do this using an include task but have found that the nant task is actually what I required.
You can have several of such targets in your 'master' file. I often use the following construction to share a set of build files between targets to make script maintenance easier.
<fileset id="buildfiles.all">
<include name="projectB.build"/>
<include name="projectB.build"/>
</fileset>
<target name="build">
<nant target="${target::get-current-target()}">
<buildfiles refid="buildfiles.all" />
</nant>
</target>
<target name="clean">
<nant target="${target::get-current-target()}">
<buildfiles refid="buildfiles.all" />
</nant>
</target>
<target name="publish">
<nant target="${target::get-current-target()}">
<buildfiles refid="buildfiles.all" />
</nant>
</target>