Вот два подхода к прерыванию сборки в случае ошибки скрипта PowerShell.
Использование exit()
для завершения процесса PowerShell
Чтобы вернуть код состояния из скрипта, который, если не-zero, будет отображаться в списке ошибок, используйте следующее:
exit(45) # or any other non-zero number, for that matter.
Это точно не помещает текст ошибки в ваш список ошибок, но завершает сценарий и что-то получает вв вашем списке ошибок, чтобы указать, какая команда до или после сборки завершилась неудачно.
Использование настраиваемой задачи MSBuild для выполнения сценария PowerShell
Я потратил немного времени на изучение деталей выполнения PowerShell.сценарий в рамках задачи MSBuild.У меня есть полная статья с примером кода в моем блоге .Проверьте это, так как оно включает в себя дополнительные обсуждения и некоторые объяснения того, как обращаться с примерами проектов.Возможно, это не полное или идеальное решение, но я получил его Работа на моей машине TM с очень простым сценарием.
Этот подход обеспечивает точность строк и столбцов при сообщении об ошибках PowerShell и дажеподдерживает поведение двойного щелчка по файлу, к которому мы привыкли в Visual Studio.Если этого не хватает, я уверен, что вы сможете расширить его, чтобы удовлетворить ваши потребности.Кроме того, в зависимости от вашей версии Visual Studio может потребоваться изменить детали, например, справочные версии сборок.
Прежде всего, создайте пользовательскую задачу MSBuild в проекте библиотеки классов.Библиотека должна ссылаться на следующие сборки для интеграции MSBuild и PowerShell.(Обратите внимание, что для этого примера требуется PowerShell 2.0.)
- Microsoft.Build.Framework (GAC)
- Microsoft.Build.Utilities.v3.5 (GAC)
- System.Management.Automation (из C: \ Program Files \ Справочные сборки \ 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
для регистрации ошибок.Когда закончите, закройте пространство выполнения и верните 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 компилирует проект, он загружает пользовательскую сборку и объект задачи и выполняет задачу.Ошибки, вызванные конвейером, извлекаются и сообщаются.