Visual Studio - Событие после сборки - выкидывание ошибок - PullRequest
15 голосов
/ 14 сентября 2010

У меня есть хороший сценарий, управляемый мощной оболочкой, который выполняет магический mumbo-jumbo для переноса всех наших плагинов в правильное место после их компиляции и сортировки их зависимостей с помощью мастер-проекта решение.

Моя проблема в том, что иногда, когда я делаю что-то глупое, я могу оказаться в состоянии, когда мой скрипт не может правильно выполнить свою работу, и выдает исключение в powershell с деталями того, что пошло не так.

Есть ли способ заставить эти исключения подойти к окну ошибок Visual Studio, чтобы при сбое моей посткомпиляции vstudio получало уведомление об ошибке и красиво форматировало его в окне вместе со всеми другими предупреждениями / ошибками?

Редактировать: Это разъяснение того, что я в идеале ищу.

удалена мертвая ссылка ImageShack

Примечание: Если вы попали сюда в поисках того, как сделать так, чтобы настраиваемые сообщения об ошибках отображались в Visual Studio (когда у вас есть контроль над сообщениями об ошибках), вы можете увидеть Рой Ответ Тинкера , чтобы узнать, как настроить ваши сообщения для отображения. Если вы заинтересованы в обнаружении непредвиденных ошибок, которые вы не можете контролировать, или в поиске более полного решения, см. Принятый ответ.

Ответы [ 2 ]

17 голосов
/ 05 января 2013

Чтобы создать сообщение об ошибке, предупреждение или сообщение, которое будет отображаться в окне списка ошибок, просто зарегистрируйте сообщение в stdout или stderr в следующем формате из сценария, инициированного событием до или после сборки.Пожалуйста, прокомментируйте или отредактируйте, если есть официальная спецификация;это только то, что я смог вывести методом проб и ошибок и просмотром результатов 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.

11 голосов
/ 14 сентября 2010

Вот два подхода к прерыванию сборки в случае ошибки скрипта 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 компилирует проект, он загружает пользовательскую сборку и объект задачи и выполняет задачу.Ошибки, вызванные конвейером, извлекаются и сообщаются.

Screenshot

...