Visual Studio-邮政构建活动 - 投掷错误
-
02-10-2019 - |
题
我有一个不错的功率壳驱动的后构建脚本,该脚本执行了一些魔术Mumbo-Jumbo,用于将我们的所有插件汇编成正确的位置并通过解决方案的主项目对其依赖性进行排序。
我的问题是,有时我会做一些愚蠢的事情时,我最终会处于无法正确执行操作的状态,并在PowerShell中抛出了一个例外,并详细介绍了出了什么问题。
是否有一种方法可以获取这些例外,可以拉到Visual Studio错误窗口,以便当我的后构建失败时,Vstudio会收到失败通知并与所有其他警告/错误一起在窗口中格式化它?
编辑:这是我理想想要的内容的澄清。
删除了死去的ImageShack链接
笔记: 如果您已经降落在这里寻找如何在Visual Studio中显示自定义错误消息(当您控制错误消息时),则可以看到 罗伊·廷克的答案 学习如何定制您的消息以显示。如果您有兴趣捕获意外的错误,无法控制或找到更完整的解决方案,请参阅可接受的答案。
解决方案
这是当PowerShell脚本错误时中断构建的两种方法。
采用 exit()
终止Powershell过程
要从脚本返回状态代码,如果非零,则会显示在错误列表中,请使用以下内容:
exit(45) # or any other non-zero number, for that matter.
这并不能准确地将错误文本列入您的错误列表,但是它确实终止了脚本,并在错误列表中获得了一些内容,以指示哪个前或后构建命令失败。
使用自定义MSBUILD任务执行PowerShell脚本
我花了一些时间来弄清在MSBuild任务中执行PowerShell脚本的详细信息。我有 完整的文章,上面有示例代码在我的博客上. 。请检查一下,因为它包括更多讨论,以及如何处理示例项目的一些解释。它可能不是一个完整或完美的解决方案,但我让它在机器上工作TM值 带有一个非常简单的脚本。
在报告PowerShell错误时,该方法提供了行和列的精度,甚至支持我们在Visual Studio中习惯的双击Takes-me-to-File行为。如果缺乏,我相信您可以扩展它以满足您的需求。另外,根据您的Visual Studio版本,您可能需要按摩诸如组装参考版本之类的详细信息。
首先,在类库项目中构建自定义MSBUILD任务。该库应参考以下组件以进行MSBUILD和POWERSHELL集成。 (请注意,此示例需要PowerShell 2.0。)
- Microsoft.build.framework(GAC)
- Microsoft.build.utilities.v3.5(GAC)
- System.Management.Automation(来自C: Program Files Reference Assemblies Microsoft WindowsPowershell V1.0)
构建任务类,并公开属性以指定PowerShell脚本的路径,例如:
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class PsBuildTask : Task
{
[Required]
public string ScriptPath { get; set; }
public override bool Execute()
{
// ...
}
}
在 Execute()
方法,启动PowerShell运行时间,执行脚本并收集错误。使用 Log
属性记录错误。完成后,关闭Runspace并返回True如果脚本记录没有错误。
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(". " + ScriptPath);
// execute the script and extract errors
pipeline.Invoke();
var errors = pipeline.Error;
// log an MSBuild error for each error.
foreach (PSObject error in errors.Read(errors.Count))
{
var invocationInfo = ((ErrorRecord)(error.BaseObject)).InvocationInfo;
Log.LogError(
"Script",
string.Empty,
string.Empty,
new FileInfo(ScriptPath).FullName,
invocationInfo.ScriptLineNumber,
invocationInfo.OffsetInLine,
0,
0,
error.ToString());
}
// close the runspace
runspace.Close();
return !Log.HasLoggedErrors;
就是这样。借助此组件,我们可以配置另一个项目以消耗MSBUILD任务。
例如,考虑一个基于C#的类库项目(.CSPROJ)。将任务集成到后构建事件中只需要几件事。
首先,仅在 <Project>
.csproj文件的节点类似:
<UsingTask TaskName="PsBuildTask"
AssemblyFile="..\Noc.PsBuild\bin\Debug\Noc.PsBuild.dll" />
TaskName应该是任务类的名称,尽管似乎不需要名称空间。 AssemblyFile
是自定义MSBUILD任务组件的绝对路径,或相对于.csproj文件的相对路径。对于GAC中的组件,您可以使用 AssemblyName
属性。
注册后,该任务可以在构建前和构建事件中使用。在 <Project>
.csproj文件的元素类似:
<Target Name="AfterBuild">
<PsBuildTask ScriptPath=".\script.ps1" />
</Target>
就是这样。当Visual Studio编译项目时,它会加载自定义组件和任务对象并执行任务。检索和报告管道引起的错误。
其他提示
要创建将出现在“错误列表”窗口中的错误,警告或消息,只需通过以下格式将消息记录到由构建前或后构建事件发起的脚本中的以下格式。如果有官方规格,请评论或编辑;这只是我能够通过反复试验和观看MSBuild的输出来推断出来的。方括号表示“可选”:
FilePath[(LineNumber[,ColumnNumber])]: MessageType[ MessageCode]: Description
举个例子:
E:\Projects\SampleProject\Program.cs(18,5): error CS1519: Invalid token '}' in class, struct, or interface member declaration
有关更多示例,请参阅“输出”窗口,以获取在Visual Studio中运行构建时可能发生的任何错误/警告/消息。