Force MSBuild 14.0 in psake build for C# 6.0 code base - msbuild

I recently updated to Visual Studio 2015 and am using the new C# 6.0 features. In VS, everything builds correctly.
However, I use PSake as build script language, and the build always fails at places where I use c# 6.0 features. How can I tell psake to use MSBuild 14.0, so that the new c# 6.0 features build correctly?
Tried & failed:
Passing in the framework version to psake: Unknown .NET Framework version, 4.6
Call the vsvars32.bat of VS2015 prior to invoking psake. PSake still uses the old MSBuild version.

I had the same issue & fixed it by configuring PSake build script to use .Net Framework 4.6, simply by adding Framework "4.6" in the beginning of the file. You may check this unit test from PSake code base dotNet4.6_should_pass.ps1

The solution described by #WahidShalaly seems to be the correct one, so use that. However, on my machine it still didn't find the correct MSBuild version so here is the workaround that I have in place instead:
Add the following task to your PSake script:
Task SetEnvironment {
Exec { & $env:VS140COMNTOOLS\vsvars32.bat }
}
This sets the environment for VS2015 compilation from within PSake.
Now add a dependency to SetEnvironment from every task that calls MSBuild and use msBuild.exe instead of just msbuild. Example:
Task Compile -Depends SetEnvironment {
Exec { & "msbuild.exe" "theSolution.sln" /p:VisualStudioVersion=14.0 }
}

Related

Duplicate error messages in .NET Core - error CS0116

Steps to reproduce
dotnet new console
(introduce a bug in Program.cs)
dotnet restore
dotnet build
The typical output would be:
Microsoft (R) Build Engine version 15.1.548.43366 Copyright (C) Microsoft Corporation. All rights reserved.
Program.cs(5,5): error CS0116: A namespace cannot directly contain members such as fields or methods [/Users/xxx/Documents/myproj/myproj.csproj]
Build FAILED.
Program.cs(5,5): error CS0116: A namespace cannot directly contain members such as fields or methods [/Users/xxx/Documents/myproj/myproj.csproj]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:01.77
You can see the error CS0116 is reported twice.
Is there a way to avoid the duplication in the reporting of errors?
The second error is part of the console logger's summary. This can be disabled by passing in /clp:NoSummary to msbuild. However, there is currently a bug in the CLI when it is the first MSBuild argument to dotnet build. Add any other MSBuild command before it to make it work. Since you want to reduce the verbosity, let's just use /nologo for the workaround:
dotnet build -c Release /nologo /clp:NoSummary
However, it works great if you use MSBuild directly:
dotnet msbuild /clp:NoSummary /p:Configuration=Release
In the upcoming 2.0.0 release, the CLI always overrides the summary parameter for dotnet build, so you'll have to use dotnet msbuild instead (I opened an issue on GitHub on that).
You can make your own MSBuild logger, instead of using the default console logger. There are really good instructions in Build loggers.
Essentially, you could make your own logger that captured all the data, and then emitted a simple summary at the end.
dotnet build /noconsolelogger /logger:YourCustomLogger.dll

specflow fails when trying to generate test execution report

I've got a project that's using SpecFlow, NUnit and Coypu to do acceptance tests on a web application. I've got the project building OK via Jenkins on a build server. Jenkins calls a psake script which runs msbuild on the specs project, then the script calls nunit-console to run the specs/tests, and then I want to generate a report from SpecFlow.
Framework "4.0"
task Default -depends RunSpecs
task BuildSpecs {
$env:EnableNuGetPackageRestore = "true"
msbuild /t:Rebuild ReturnsPortal.Specs.csproj
}
task RunSpecs -depends BuildSpecs {
exec { & "C:\path\to\NUnit 2.5.9\bin\net-2.0\nunit-console-x86.exe" /labels /out=TestResult.txt /xml=TestResult.xml .\bin\Debug\TheWebApp.Specs.dll }
exec { & "C:\path\to\SpecFlow\1.8.1\specflow.exe" nunitexecutionreport TheWebApp.Specs.csproj /out:SpecResult.html }
}
That last exec call to specflow.exe fails though, with:
The element <ParameterGroup> beneath element <UsingTask> is unrecognized. C:\Program Files (x86)\Jenkins\jobs\TheWebApp\workspace\Web\Sites\TheWebApp.nuget\nuget.targets
A bit of googling hints that maybe it's a problem with the msbuild version being used (e.g. here, here). But I have Framework "4.0" in my psake script, and the Specs project is targeting .NET Framework 4.0, and it builds fine in the build step, so I'm not sure why specflow seems to be using an earlier version of msbuild. Or is maybe the problem somewhere else?
This was the answer for me, from the SpecFlow Wiki:
Important for .NET 4.0 projects: Because specflow.exe is compiled for .NET 3.5, it cannot load .NET 4.0 assemblies by default. To generate this report for .NET 4.0 projects, you have to force specflow.exe to use the .NET 4.0 runtime by using the config file. Just copy the config below and create a specflow.exe.config file and put it next to your specflow.exe and you will be able to create the step definition report.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0.30319" />
</startup>
</configuration>
I attempted to use the config file solution suggested above. It worked for testing locally, but as soon as I pushed my code to our CI environment it choked on it since the CI environment doesn't have that config file. We restrict out CI environment to only use clean versions of the various packages, so we didn't want to try to inject the special config into the CI server.
We noticed that SpecFlow works just fine with several of our .NET 4.0 projects without the special config file. After a little research, the actual 'problem' appears to be NuGet 2.1. Everything works fine for .NET 4.0 projects with NuGet 1.7.
Somewhere between 1.7 and 2.1 NuGet introduced new features in the NuGet.targets file that aren't supported by the older versions of MSBuild. Specifically the problem seems to be the <ParameterGroup> beneath element <UsingTask>, as explained by the error message.
A cursory glance at the targets file indicates that the section is responsible for keeping NuGet up to date. Removing this section completely resolves the issue in the same manner that adding the config file above does, albeit also removing the self-update functionality that is seems to provide. Given that the .targets file is committed to the repository, this solution also works on our CI environment with out any changes on the CI side.
It's not necessarily a better solution than ngm's, it's just a different one. Depending on your environment, this may be a preferable way to go, or perhaps not.

NAnt + MSBuild (4.0) == MSBuild launch failure w/directory not found error

Ive got CC.Net and NAnt (and MSBuild) running on a new VM-based build server (Win7-64 Pro).
CC.Net can call MSBuild just fine - but I run into problems there when dealing with project-scope builds. The conditionals just dont have what I need. Not even close.
So I decide to deal with those conditions by calling MSBuild with NAnt, which fails every time. When I run the nant script from the command prompt, I get this:
[loadtasks] Failure scanning "C:\nant\bin\extensions\common\2.0\Collection
Gen.dll" for extensions. Could not load file or assembly 'Microsoft.VSDesigner,
Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of
its dependencies. The system cannot find the file specified.
Buildfile: file:///c:/c7/projects/dyndata/dyndata.build
Target framework: Microsoft .NET Framework 4.0
Target(s) specified: build
build:
[loadtasks] Scanning directory "c:\nantcontrib\bin\lib" for extension assemblies
.
[echo] Building DynData v7.0.7
BUILD FAILED
c:\c7\projects\dyndata\dyndata.build(24,12):
Failed to start MSBuild.
c:\c7\projects\dyndata\dyndata.build(24,12):
External Program Failed: C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbui
ld.exe (return code was 1)
Total time: 0.4 seconds.
c:\c7\projects\dyndata\dyndata.build(24,12):
Failed to start MSBuild.
c:\c7\projects\dyndata\dyndata.build(24,12):
'C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe' failed to start.
The directory name is invalid
The Designer assembly is present on this machine, which has VS2010 Pro installed on it.
The build folder is correct.
The framework folder is correct.
Umpteen searches for nant/msbuild and this message have yielded nothing substantive.
These items have been tried and failed to change the results:
Nant msbuild task with .net 4.0 rc
.NET projects build automation with NAnt/MSBuild + SVN (tho I am using Vault)
I tried to build the nant code so I could debug the problem via VS2010's debugger but the source project is an unworkable mess and wont even begin to build.
Ideas are welcome:)
I think the first error about Microsoft.VSDesigner is just a warning - not a failure. On my developer box and build server I have VS2005 and VS2010 Pro installed and I do not have Microsoft.VSDesigner version 7 installed. I have version 8 and 9 installed but not 7.
It looks like the "build" target is running in nant and then then it fails. You are loading the tasks from nantcontrib then trying to start msbuild. How are you starting msbuild? Could you post the part of the nant file that starts it? What version of nant are you using? Does running nant with -v and -debug+ flags show anything helpful?

MSBUILDEMITSOLUTION not working with .NET 4?

In prior versions of MSBuild, you could set an environment variable named MSBUILDEMITSOLUTION to 1 to get an XML version of a solution (.sln) file that could be parsed. According to the MSBuild Team Blog, that's still in the version that ships with Visual Studio 2010, but it does not seem to be working.
Has anyone managed to get this working with MSBuild 4.0? If so, what is required?
(We use this to find and run convention-based unit tests with an NAnt script.)
Set MSBuildEmitSolution=1 and then build from the command line. You should then see a MySolution.sln.metaproj file near MySolution.sln.
Notes:
If you open a command prompt window, then set the env var via System Settings, you will have to open a new command prompt.
You'd think you could also use msbuild /p:MSBuildEmitSolution=1, but you can't.

Nant msbuild task with .net 4.0 rc

How do I need to indicate to the msbuild task in my nant script that it should use .net 4.0 rc?
I think the latest NAnt/NAntContrib defaults to .NET 3.5, so you'll have to change that to 4.0. There is a NAnt property to handle that (<property name="nant.settings.currentframework" value="net-4.0" />), which should go near the top of your NAnt build file.
Next, you'll need to go into your NAnt's configuration file and add the 4.0 node, so that NAnt (and by extension NantContrib) are aware of the new CLR version.
The first option is to change the executable that MSBuild task uses. According to the doco this is a framework property so you would need to change it in the main nant config file rather than in you're individual script, and you would have to do it on every machine you plan on building the script on.
The other option is to use the exec task instead. This question and answer should help with that.
EDIT: Forgot to mention the directories MSBuild is in. To change versions just use a different MSBuild.
2.0: %windir%\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe
3.5: %windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe
4.0b2: %windir%\Microsoft.NET\Framework\v4.0.21006\MSBuild.exe