问题
I'm attempting to programmatically build a project which uses C#7, and therefore MSBuild 15, but this task is failing seemingly because of mismatched assembly references.
Here is my code:
string projectFilePath = Path.Combine(args.Any() ? args.First() :@"C:\Users\newsoni\Documents\Visual Studio 2017\Projects\ConsoleApp2\ConsoleApp2.sln");
ProjectCollection pc = new ProjectCollection();
Dictionary<string, string> globalProperty = new Dictionary<string, string>();
globalProperty.Add("Configuration", "Debug");
globalProperty.Add("Platform", "x86");
BuildParameters bp = new BuildParameters(pc);
bp.Loggers = new ILogger[] { new Logger(), new ConsoleLogger(), };
BuildRequestData BuidlRequest = new BuildRequestData(projectFilePath, globalProperty, "4.0", new string[] { "Build" }, null);
BuildResult buildResult = BuildManager.DefaultBuildManager.Build(bp, BuidlRequest);
Here is the error message:
C:\Users\newsoni\Documents\Visual Studio 2017\Projects\ConsoleApp2\ConsoleApp2.sln.metaproj : error MSB4127: The "Error" task could not be instantiated from the assembly "Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". 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 'Microsoft.Build.Tasks.Error' to type 'Microsoft.Build.Framework.ITask'.
C:\Users\newsoni\Documents\Visual Studio 2017\Projects\ConsoleApp2\ConsoleApp2.sln.metaproj : error MSB4060: The "Error" task has been declared or used incorrectly, or failed during construction. Check the spelling of the task name and the assembly name.
Here is a link to a project you can use to recreate the issue:
https://drive.google.com/a/xibis.com/file/d/0B-mqMIMqm_XHcVRJQmtxQkd1b3c/view?usp=sharing
You will have to change the path in the code to a project on your own machine, but it doesn't seem to matter if this is a VS 2017 project or earlier.
One other thing that may or may not be relevant, I noticed that the Microsoft.WebApplication.Build.Tasks.Dll in this folder:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications
Still seems to be referencing Microsoft.Build.Framework.dll version 14, not 15 as I would have expected.
回答1:
It turns out there are two issues in my test project. The first is due to the naming of the project.
However there is a second issue which is due to the references not being correct. To use MSBuild 15 programmtically you must install the following packages:
Install-Package Microsoft.Build -Version 15.1.1012
Install-Package Microsoft.Build.Framework -Version 15.1.1012
Install-Package Microsoft.Build.Tasks.Core -Version 15.1.1012
Install-Package Microsoft.Build.Utilities.Core -Version 15.1.1012
Install-Package Microsoft.Net.Compilers -Version 2.2.0
There is one more step which is nuts and completely undiscoverable. You must now add a reference to this DLL which should be relative to your solution folder:
packages\Microsoft.Net.Compilers.2.2.0\tools\Microsoft.Build.Tasks.CodeAnalysis.dll
回答2:
I opened a support ticket with Microsoft and they have confirmed that this is a bug in Visual Studio 2017.
They are aiming to get a fix for this into update 3 for Visual Studio, but this may slip.
This issue tracks the bug:
https://github.com/Microsoft/msbuild/issues/2194
There is no workaround at present for this API, but you can invoke the MSBuild exe using Process
as an alternative.
回答3:
If you have MSBuild installed on your PC, either directly or through Visual Studio, the proper fix is to use the package Microsoft.Build.Locator which will find that installed version and execute the build using it.
Install these packages
Microsoft.Build
Microsoft.Build.Framework
Microsoft.Build.Locator
The first 2 are needed so that the code can compile but should be excluded from the project output.
In your application startup add the following line of code, this only has to run once.
Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults();
Remove any additional binding redirects in your app.config
that are specific to Microsoft.Build
or other build libraries. The call to the Microsoft.Build.Locator
assembly will ensure that these redirects take place automatically.
References
- Update an existing application for MSBuild 15
- Github MSBuildLocator.
来源:https://stackoverflow.com/questions/43662328/msbuild-15-the-error-task-could-not-be-instantiated