以编程方式构建msbuild 15项目 [英] Building msbuild 15 project programmatically
问题描述
我正在尝试构建一个使用VS2017创建的简单C#7类库项目.
I'm trying to build a simple C# 7 class library project created with VS2017.
来自框架程序集的MSBuild已过时,因此我引用Visual Studio(C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin
)中MSBuild文件夹中的Microsoft.Build
,Microsoft.Build.Engine
和Microsoft.Build.Framework
.
MSBuild from framework assemblies is outdated, so I'm referencing Microsoft.Build
, Microsoft.Build.Engine
and Microsoft.Build.Framework
from MSBuild folder within visual studio (C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin
).
还是,当我这样做时:
using (var collection = new ProjectCollection())
{
var proj = collection.LoadProject(@"c:\projects\Sample\Sample.csproj"); // <-- exception
proj.Build(new[] {new ConsoleLogger()});
}
我得到InvalidProjectFileException: The tools version "15.0" is unrecognized. Available tools versions are "4.0", "2.0".
是否有使用最新的构建工具和C#7编译器的编程方式来调用构建?
Is there programmatic way to invoke build using the latest build tools and C# 7 compiler?
推荐答案
我对团队有类似的需求,并且为C#编写了一个Builder库,该库支持多个Visual Studio版本. 我无法使Project.Build函数正常工作,所以我直接执行MsBuild.exe.
I had similar needs for my team and I wrote a Builder library for C# that supports several versions of Visual Studio. I could not make the Project.Build function work properly, so I went for executing MsBuild.exe directly.
我是如何建造的:
根据Visual Studio版本的项目:
Of the Project according to the Visual Studio version:
- 2010,2012 => 4.0
- 2013 => 12.0
- 2015 => 14.0
- 2017 => 15.0
具有包含我需要构建的所有项目的Projects属性
With Projects property containing all the project I need to build
值与项目相同
在注册表中找到
Registry.LocalMachine.OpenSubKey($@"SOFTWARE\Microsoft\MSBuild\ToolsVersions\{msBuildVersion}")
15.0
不再在注册表中,您需要使用Nuget包 Microsoft.VisualStudio.Setup.Configuration.Interop
var query = new SetupConfiguration();
var query2 = (ISetupConfiguration2)query;
var e = query2.EnumAllInstances();
var helper = (ISetupHelper)query;
int fetched;
var instances = new ISetupInstance[1];
do
{
e.Next(1, instances, out fetched);
if (fetched > 0)
{
var instance = instances[0];
var instance2 = (ISetupInstance2)instance;
var state = instance2.GetState();
// Skip non-complete instance, I guess?
// Skip non-local instance, I guess?
// Skip unregistered products?
if (state != InstanceState.Complete
|| (state & InstanceState.Local) != InstanceState.Local
|| (state & InstanceState.Registered) != InstanceState.Registered)
{
continue;
}
var msBuildComponent =
instance2.GetPackages()
.FirstOrDefault(
p =>
p.GetId()
.Equals("Microsoft.Component.MSBuild",
StringComparison.InvariantCultureIgnoreCase));
if (msBuildComponent == null)
{
continue;
}
var instanceRootDirectory = instance2.GetInstallationPath();
var msbuildPathInInstance = Path.Combine(instanceRootDirectory, "MSBuild", msBuildVersion, "Bin", "msbuild.exe");
if (File.Exists(msbuildPathInInstance))
{
return msbuildPathInInstance;
}
}
} while (fetched > 0);
执行MsBuild.exe
并使用自定义XML记录器构建序列化的项目-您可以使用 MsBuildExtensionPack 提供的项目
从Xml反序列化结果摘要,并使用它来确定构建是否失败,发生了哪些错误和警告等.
Deserialize the result summary from Xml and use it to determine if build failed or not, which errors and warnings occurred etc.
这篇关于以编程方式构建msbuild 15项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!