我正在考虑通过直接点击MSBuild程序集从Powershell脚本运行MSBuild(而不是查找MSBuild安装路径并启动msbuild.exe作为子进程)。
有人这样做过吗?运行构建的最简单,最直接的方法是什么?你想指出哪种技术都有利弊吗? (我对在与脚本的其余部分相同的进程/ appdomain中运行msbuild可能引起的任何问题特别感兴趣。)
目前我的想法是这样的:
[void][System.Reflection.Assembly]::Load('Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][Microsoft.Build.BuildEngine.Engine]::GlobalEngine.BuildProjectFile("path/main.proj")
答案 0 :(得分:14)
工作和生成输出的最简单的嵌入式构建调用是:
[void][System.Reflection.Assembly]::Load('Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
$engine = New-Object Microsoft.Build.BuildEngine.Engine
$engine.RegisterLogger((New-Object Microsoft.Build.BuildEngine.ConsoleLogger))
$engine.BuildProjectFile('fullPath\some.proj')
然而,事实证明直接在Powershell(V1)中嵌入MSBuild是有问题的:
'MSBUILD : warning MSB4056: The MSBuild engine must be called on
a single-threaded-apartment. Current threading model is "MTA".
Proceeding, but some tasks may not function correctly.'
为什么我们为什么在管理环境中工作时仍然在2009年支付COM税?
我的结论是在Powershell(V1)中嵌入MSBuild并不是一个好主意。作为参考,我还包括我最终使用的基于流程的方法:
[void][System.Reflection.Assembly]::Load('Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
$msbuild = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFrameworkFile("msbuild.exe", "VersionLatest")
&$msbuild fullPath\some.proj
答案 1 :(得分:5)
我非常强烈建议查看PSake。
让我引用该页面的一部分:
请记住,psake是围绕PowerShell的语法糖。所以你可以在PowerShell中做任何事情,你可以用psake做。这意味着您可以运行MSBuild,NAnt或其他脚本。无需完全替换当前的构建系统。您可以使用psake自动化和扩展它!
psake会自动将适当版本的.NET Framework添加到其路径中。因此,您可以访问MSBuild,csc.exe,vbc.exe或$ env:windir \ Microsoft.NET \ Framework \ $ version \中安装的任何其他工具,而不使用完全限定的路径。
答案 2 :(得分:3)
另一种可能更有用的方法是创建一个msbuild cmdlet。 MsBuild有一个很好的API,有很多关于如何从C#/ VB等编译语言中使用它的示例。构建一个可以为powershell脚本提供更好语法的cmdlet非常容易。
答案 3 :(得分:3)
我一直在寻找同样的事情。在JaredPar的带领下,我找到了以下内容:
这是制作cmdlet的方法。
MSBuild API是这些命名空间的一部分:
Microsoft.Build.Framework
Microsoft.Build.BuildEngine
可以在这里找到MSBuild文档(这完整性比回答您的问题更多):
答案 4 :(得分:0)
曾几何时我一直在玩增强的MSBuild构建过程(比如,更积极地跳过构建的某些部分)。
有两种选择:
我已经实现了两者并且不得不放弃#1,因为它不够灵活。
例如,MSBuild在其.config文件中有大量的程序集绑定重定向。
同时托管MSBuild及其API的Visual Studio进程(devenv.exe
)最终将这些进程复制到其devenv.exe.config
中。我的.exe.config
也必须拥有这些,但它会将您绑定到特定的MSBuild版本。当然,您必须修改配置。实际上这不是PS的选项,所以我怀疑你是否能得到一个非常稳定的解决方案。