How to determine the version of MSBuild an assembly was built with? - c#

I'm trying to run my first xUnit.net tests via MSBuild and I'm following the documentation here. Here is my project file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build;Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\xunit.runner.msbuild.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.runner.msbuild.props"
Condition="Exists('..\packages\xunit.runner.msbuild.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.runner.msbuild.props')" />
<!--Extra lines omitted for brevity-->
<UsingTask AssemblyFile="xunit.runner.msbuild.dll"
TaskName="Xunit.Runner.MSBuild.xunit"/>
<Target Name="Test">
<xunit Assembly="bin\$(Configuration)\Core.dll"/>
</Target>
</Project>
When I run MSBuild, however, it gives me the following error:
C:\Users\James\libvideo\tests\Core\Core\Core.csproj(85,5):
error MSB4127: The "xunit" task could not be instantiated from the assembly "C:\Users\James\libvideo\tests\Core\packages\xunit.runner.msbuild.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.runner.msbuild.dll".
Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework.
Unable to cast object of type 'Xunit.Runner.MSBuild.xunit' to type 'Microsoft.Build.Framework.ITask'.
I've checked that the spelling is correct, however it's still giving me this error. The xUnit.net documentation says nothing about this (or at least from where I've looked), so I'm stuck at what to do now. It tells me that I can check the version of MSBuild the assembly was built with, but how do I do that? Is MSBuild even required to build an assembly?
(MSBuild says it's version 14.0.23107.0, I have VS2015 if that's important.)
Thank you!

MSBuild is based on tasks and targets. You can see what it looks like in a .csproj, usually at the end. The task object is defined in the version of MSBuild you are using, located in, for example, C:\Program Files (x86)\MSBuild\12.0\Bin.
Version of MSBuild typically follows the .NET framework like this:
version 1.0: 2006
version 2.0:
version 3.5: 2011
You probably miss the right version of MSBuild. Or you can try with a different version than ToolsVersion="14.0".

Related

"Not a valid framework" (MM0140) error when trying to build Xamarin native bindings library for framework targeting net6-macos

I have working native bindings library targeting old xamarin.mac (xamarin.full net framework 4.8) built with mono.
It is binding ScritptingBridge.framework, not a static library. It is builds and works as expected.
Note: full project for experiments may be found here: https://github.com/snechaev/net6nativeBindingsError
Now I'm trying to migrate to newest net6-macos. To do so I do the following
converted main app project to the sdk style and target net6-macos. If I will temporary remove native bindings dependencies, this will build fine.
converted native bindings project to the sdk style and perform the following fixes suggested by the comiler errors
changed version to avoid wildcards
replaced [assembly: LinkerSafe] with AssemblyMetadata("IsTrimmable", "True")]
added explicit NativeReferecnce to the framework I'm trying to bind.
Final csproj content for native bindings project:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6-macos</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>NativeBindingsLib</RootNamespace>
<AssemblyName>NativeBindingsLib</AssemblyName>
<IsPackable>false</IsPackable>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<IsBindingProject>true</IsBindingProject>
<NoBindingEmbedding>true</NoBindingEmbedding>
</PropertyGroup>
<ItemGroup>
<ObjcBindingApiDefinition Include="ApiDefinition.cs" />
<ObjcBindingCoreSource Include="StructsAndEnums.cs" />
<NativeReference Include="/System/Library/Frameworks/ScriptingBridge.framework" Kind="Framework" />
</ItemGroup>
</Project>
When I trying to build the only bindings library with dotnet build it builds without errors.
But when I try to build the application project (app.csproj in the sample repository), which is referencing (via the the ProjectReference) the binding library, I got the following errors:
ILLINK: Error MM0140: File '/Users/user/work/MonoBindingTest/net6/app/obj/Debug/net6.0-macos/osx-x64/linker-cache/NativeBindingsLib.resources/ScriptingBridge.framework/ScriptingBridge' is not a valid framework. (MM0140) (app)
ILLINK: Error MM2342: The linker step 'Extract Binding Libraries' failed during processing: File '/Users/user/work/MonoBindingTest/net6/app/obj/Debug/net6.0-macos/osx-x64/linker-cache/NativeBindingsLib.resources/ScriptingBridge.framework/ScriptingBridge' is not a valid framework. (MM2342) (app)
I double checked the framework path and it is ok. I also tried to add ScriptingBridge.framework into the XCode project and verified that the path is the same.
I also will be happy to get any samples of working net6-macos targeted native bindings projects for frameworks (not a static libraries) for further experiments on my own.
Full project mey be found here (both mono-targeted and net6-targeted): https://github.com/snechaev/net6nativeBindingsError
Finally, I posted the issue in the xamarin repo on github https://github.com/xamarin/xamarin-macios/issues/15485.
And ducting the discussion and experiments we concluded the following:
MM0140 is because the ScriptingBridge is the system framework and this is the special case.
you should not use NativeReference for the system frameworks as it will try to copy the framework into your bundle and this is not what you want for the system framework
initially I was missleaded by the following error
MSBuild : error MM7068: Can't create a binding resource package unless there are native references in the binding project.
so I decided to add NativeReference pointing ScriptingBridge.
So, the final solution is that the "at least one NativeReference" compiler check is excessive and it will be removed it net7 (https://github.com/xamarin/xamarin-macios/issues/15489).
The temporary workaround for net6 is to add the fake NativeReference to the empty static library to make compiler happy.
<NativeReference Include="/Users/sergey/work/MonoBindingTest/net6/test.dylib" Kind="Static"/>
I believe that it is possible to specify NativeReference to point to the source code (C++) instead of binary file and provide an additional command to build such a C++ code into the binary during the build process of native bindings library.
Additional note: the MM0140 error was called MT0140 in the previous versions of xamarin. So, this note may help other to find this post.

Visual Studio 16.8 breaks .NET Framework 4.8 WPF build

I've now updated to Visual Studio 16.8, and with that, my existing (large) solution fails to build any WPF projects. Error messages such as the following everywhere:
10>C:\...\src\UserInterface\DataWriterMonitor\App.xaml.cs(5,25,5,28): error CS1558: "App" hat keine passende statische Main-Methode.
10>C:\...\UserInterface\DataWriterMonitor\App.xaml.cs(9,4,9,23): error CS0103: Der Name "InitializeComponent" ist im aktuellen Kontext nicht vorhanden.
Obviously, it's failing to pre-process the xaml files. When I change the csproj header of the offending project from <Project Sdk="Microsoft.NET.Sdk"> to <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> I get:
10>C:\Program Files\dotnet\sdk\5.0.100\Sdks\Microsoft.NET.Sdk.WindowsDesktop\targets\Microsoft.WinFX.targets(240,9): error MC1000: Unbekannter Buildfehler, "Could not find assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Either explicitly load this assembly using a method such as LoadFromAssemblyPath() or use a MetadataAssemblyResolver that returns a valid assembly."
This even happens if I remove all direct references from the project.
Different other approaches (including setting the sdk to 4.8 in global.json) generated different error messages, but didn't work either.
How can I make that the build does not use the 5.0 SDK? I need it installed for other projects, but here I just want my solution to build as before with .NET Framework 4.8.
Note: I've tried the sample .NET 4.8 WPF app. This one builds, but it uses the old project file format. If I change it to the new format, I get similar problems. After some fiddling, that now works, possibly because this otherwise empty project has no references at all.
I apparently did too many things at once. Using a global.json with
{
"sdk": {
"version": "3.1.101"
}
}
and no other changes (especially no change to <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">) fixed the build.
I removed <usewpf>true</usewpf> from my projects

MSB4062: The Microsoft.Build.Tasks.AspNetCompiler task could not be loaded from the assembly Microsoft.Build.Tasks.Core

I have AspNet.MVC application and want to build MVC views during the build (only in Release configuration).
I create this target
<Target Name="BuildViews" Condition="'$(configuration)'=='Release'" AfterTargets="Build">
<AspNetCompiler VirtualPath="/" PhysicalPath="$(ProjectDir)" />
</Target>
In Debug configuration it builds
In Release it fails with error
error MSB4062: The "Microsoft.Build.Tasks.AspNetCompiler" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
Installing Microsoft.Build.Tasks.Core, adding UsingTask and other manipulations doesnt help(
Maybe anyone knows the solution?
Target framework - new 4.8
C# version - 8
IDE - JetBrains Rider 2019.3.1
MSBuild Path - C:\Program Files\dotnet\sdk\3.1.101\MSBuild.dll
Project format - Microsoft.NET.Sdk (.net core format)
Also, i try to change MSBuild Path (in rider settings)
If i change it to exe-file in rider folder C:\Program Files\JetBrains\JetBrains Rider 2019.3.1\tools\MSBuild\Current\Bin\MSBuild.exe, it works
But this is not a solution, because it doesnt work on TeamCity agents, where rider is not installed
Just had the same issue with the BuildTools in Team City... Depending on what build tools you need there are different paths to it as some exist in \Microsoft Visual Studio\2019\Professional\MSBuild\ and some are in MSBuild\2019\<path>. For me this issue was resolved by updating my .config towards VS and not the build tools.

Error: Could not load file or assembly 'Microsoft.Win32Registry' from .NET Standard Library Consumed by .NET Framework Console App

The Problem
The Microsoft.Win32.Registry nuget package is giving me a lot of issues . We had .NET Framework 4.7.2 library that had a helper class that used that package and worked fine from a .NET Framework 4.7.2 unit test project. We recently converted the library to target .NET Standard 2.0, and now this class breaks when used with the following error:
ERROR: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Win32.Registry, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.Win32.Registry, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at NetStandardRegistryLib.RegistryUtil..ctor(String remoteMachineName)
at NetStandardRegistryLib.Program.Main(String[] args) in C:\src\Microsoft.Win32.Registry-IssueRepro\FrameworkRegistry\RegistryEditor\Program.cs:line 21
When I look at output of the Console project, I don't see the Microsoft.Win32.Registry.dll in the output.
Using ILSpy and loading my .exe - it seems it would try to resolve the .dll from my dotnet core installation, which wouldn't work since it's a .NET Framework app.
To Reproduce
I've created a repo that reproduces for me on my Windows 2010 machine. You can find it here: https://github.com/TylerNielsen/Microsoft.Win32.Registry-IssueRepro
Clone the repo, then open and build the RegistryEditor project.
Using Powershell or your favorite editor - call the tool with three required arguments [remoteMachineName] [Environment variable name to set] [Value to set on the environment variable] **
** Note, this actually requires a remote machine you can reference by IP address. For some reason using 127.0.0.1 doesn't work for me, but I'm unsure why. The use case for this utility is for accessing remote machine environment variables.
Other Notes
When I create a .NET Framework Class Library to use for unit tests and reference the same .NET Standard Library - the Microsoft.Win32.Registry package is included and the utility runs just fine.
In your repo, if you look into both csproj files you'll see they are quite different. The NetStandardRegistryLib.csproj is the new format, the RegistryEditor.csproj is the old one.
Your problem is that old style projects do not resolve dependencies transitively. RegistryEditor will not copy dependencies of its own dependency NetStandardRegistryLib.
There are at least two ways to solve your problem:
Just add Microsoft.Win32.Registry Nuget package to RegistryEditor project explicitly. That'll make the Microsoft.Win32.Registry.dll to appear in the RegistryEditor build folder.
Convert the RegistryEditor.csproj to new format. It's not limited to netstandard builds, you can use it for builds targeting .Net Framework versions as well. And it does resolve dependencies transitively!
Here's a long guide for how to do the conversion in general https://natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/
Since your project is quite simple, I've converted it for you. Just replace the content of RegistryEditor.csproj with the code below. It's still targeting net472.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<AssemblyName>RegistryEditor</AssemblyName>
<RootNamespace>RegistryEditor</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NetStandardRegistryLib\NetStandardRegistryLib.csproj" />
</ItemGroup>
</Project>
Note that several properties that used to be in AssemblyInfo.cs file are provided by csproj file properties now, so you need to remove them from AssemblyInfo.cs to fix compilation errors:
[assembly: AssemblyTitle("RegistryEditor")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RegistryEditor")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

XUnit doesn't work during MSBuild

I'm a newcomer to Xunit and I'm trying to run it via MSBuild. Following the documentation, here is my build script so far:
<UsingTask AssemblyFile="..\packages\xunit.runner.msbuild.*\build\*\xunit.runner.msbuild.dll"
TaskName="Xunit.Runner.MSBuild.xunit"/>
<Target Name="Test">
<xunit Assemblies="bin\$(Configuration)\Core.dll"/>
</Target>
When I run MSBuild on the .csproj, however, it gives me the following error:
error MSB4127: The "Xunit.Runner.MSBuild.xunit" task could not be instantiated from the
assembly "C:\Users\James\libvideo\tests\Core\packages\xunit.runner.msbuild.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.runner.msbuild.dll".
Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework
assembly as the one installed on your computer and that your host application is not missing
a binding redirect for Microsoft.Build.Framework. Unable to cast object of type
'Xunit.Runner.MSBuild.xunit' to type 'Microsoft.Build.Framework.ITask'.
I've checked that the path it's looking for exists, and I've also followed the steps here. No luck, however. What can I do to resolve this?
This error is normally due to a mismatch in your MSBuild Tools Version. This is defined in the <Project> root element. The tools version you are running is from a version of the ITask interface different from that of the xunit runner so without an assembly binding redirect, it cannot cast between the different versions of ITask.
https://msdn.microsoft.com/en-us/library/bb383796.aspx

Categories