我想在 Visual Studio 2017 中以编程方式构建一个全新添加的标准 ASP (MVC) Web 应用程序。因此,我使用了一个控制台应用程序,该应用程序使用 Microsoft.Build.Evaluation.Project.Build() 打开和编译项目。下面概述了构建的控制台应用程序。需要构建的项目是刚刚从 Visual Studio 中的向导生成的标准 ASP MVC .Net 应用程序。在我的 Visual Studio 2017 版中,它编译得很好。但是,如果我想使用我的应用程序编译它,在打开项目时,它会出现错误:
Microsoft.Build.Exceptions.InvalidProjectFileException 发生 HResult=0x80131500 消息=未找到导入的项目“C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets”。确认声明中的路径正确,并且该文件存在于磁盘上。
现在,如果您在记事本中打开 web 应用程序的 csproj 文件,它会告诉您它想要在以下位置找到它的导入项目:
导入项目="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" 条件="'$(VSToolsPath)' != ''"
根据错误,在我看来工具路径是“C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0”但是 WebApplications\Microsoft.WebApplication.targets 位于“C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0"
一种解决方法显然是将 WebApplications 文件夹从 v14.0 复制到 v15.0。然后它愉快地编译。但问题是:为什么一个标准生成的项目指向一个不存在的目录?为什么 Visual Studio 本身可以应对这种错误的路径?有比复制 WebApplications 文件夹更好的解决方案吗?
以下是打开和编译 Web 项目的代码:
using System;
using Microsoft.Build.Logging;
namespace CompilerApp
{
class Program
{
static void Main(string[] args)
{
//string projectfile = @"C:\temp\CompilerApp\MyCSharp7\MyCSharp7.csproj";
string projectfile = @"C:\temp\CompilerApp\WebApplication1\WebApplication1.csproj";
UnloadAnyProject();
Microsoft.Build.Evaluation.Project p = new Microsoft.Build.Evaluation.Project(projectfile);
FileLogger loggerfile2 = new FileLogger();
loggerfile2.Parameters = @"logfile=C:\temp\CompilerApp\myapp.msbuild.log";
bool buildresult = p.Build(loggerfile2);
if (buildresult)
{
Console.WriteLine("project compiled");
}
else
{
Console.WriteLine("project not compiled, check {0}", @"C:\temp\myapp.msbuild.log");
}
p.Save();
UnloadAnyProject();
}
private static void UnloadAnyProject()
{
Microsoft.Build.Evaluation.ProjectCollection projcoll = Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection;
foreach (Microsoft.Build.Evaluation.Project pr in projcoll.LoadedProjects)
{
Microsoft.Build.Evaluation.ProjectCollection mypcollection = pr.ProjectCollection;
mypcollection.UnloadProject(pr);
}
}
}
}