Как получить уведомление о завершении успешной сборки?

Я пишу надстройку VS, и мне нужно запустить определенный метод после успешной сборки. Я пробовал использовать dte.Events.BuildEvents.OnBuildDone, но это событие происходит даже в случае сбоя сборки.

Есть ли какое-либо свойство или какое-то другое событие, которое я должен использовать?

Ответ 1

Событие OnBuildDone не может рассказать вам, что произошло. Некоторые проекты в решении могли бы быть построены правильно, а некоторые - нет. Вместо этого вам понадобится OnBuildProjConfigDone. Пожары для каждого проекта, аргумент Success указывает, работает ли он.

Ответ 2

Как правило, вам нужно обрабатывать несколько построенных проектов. Это может быть сборка решений или создание проекта, который зависит от другого проекта.

Итак, чтобы выяснить, когда закончилась успешная сборка, вам нужно использовать комбинацию из двух событий сборки:

OnBuildProjConfigDone и OnBuildDone.

Вам также потребуется переменная-член для отслеживания общего состояния сборки.

Ваш обработчик OnBuildProjConfigDone будет вызван для каждого проекта, который будет создан, и ему передается bool, чтобы сообщить вам, была ли эта сборка проекта успешной. Назначьте этот результат своей переменной-члену, чтобы отслеживать общий статус.

Наконец, ваш обработчик OnBuildDone будет вызван. Здесь вы можете посмотреть свою переменную-член, чтобы увидеть, не удалось ли построить проект.

Вот пример кода с расширением, которое я написал для VS2012. Расширение предоставляет команду "custom build", которая строит активный проект и запускает отладчик, если сборка прошла успешно.

private bool _overallBuildSuccess;
private bool _customBuildInProgress;

private void CustomBuild_MenuItemCallback(object sender, EventArgs e)
{
    // Listen to the necessary build events.
    DTE2 dte = (DTE2)GetGlobalService(typeof(SDTE));
    dte.Events.BuildEvents.OnBuildDone += BuildEvents_OnBuildDone;
    dte.Events.BuildEvents.OnBuildProjConfigDone += BuildEvents_OnBuildProjConfigDone;

    try
    {
        // Build the active project.
        _customBuildInProgress = true;
        dte.ExecuteCommand("Build.BuildSelection");
    }
    catch (COMException)
    {
        _customBuildInProgress = false;
        WriteToOutputWindow("Build", "Could not determine project to build from selection");
    }
}

private void BuildEvents_OnBuildProjConfigDone(string project, string projectConfig, string platform, string solutionConfig, bool success)
{
    // Ignore this build event if we didn't start it.
    if (!_customBuildInProgress)
    {
        return;
    }

    // Keep track of the overall build success.
    _overallBuildSuccess = success;
}

private void BuildEvents_OnBuildDone(EnvDTE.vsBuildScope scope, EnvDTE.vsBuildAction action)
{
    // Ignore this build event if we didn't start it.
    if (!_customBuildInProgress)
    {
        return;
    }

    _customBuildInProgress = false;

    if (_overallBuildSuccess)
    {
        // Launch the debugger.
        DTE2 dte = (DTE2)GetGlobalService(typeof(SDTE));
        dte.ExecuteCommand("Debug.Start");
    }
    else
    {
        WriteToOutputWindow("Build", "Custom build failed.");
    }
}

private void WriteToOutputWindow(string paneName, string message)
{
    DTE2 dte = (DTE2)GetGlobalService(typeof(SDTE));

    Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
    OutputWindow outputWindow = (OutputWindow)window.Object;

    OutputWindowPane targetPane = outputWindow.OutputWindowPanes.Cast<OutputWindowPane>()
        .FirstOrDefault(x => x.Name.ToLower() == paneName.ToLower());

    if (targetPane == null)
    {
        targetPane = outputWindow.OutputWindowPanes.Add(paneName);
    }

    targetPane.Activate();
    outputWindow.ActivePane.OutputString(message);
    outputWindow.ActivePane.OutputString(Environment.NewLine);
}

Ответ 3

Для будущих читателей ознакомьтесь с этой статьей.

http://blogs.msdn.com/b/alexpetr/archive/2012/08/14/visual-studio-2012-and-buildevents-in-addins.aspx

и/или

http://support.microsoft.com/kb/555102/en-us

В принципе, может быть ошибка. Обход - это установить переменную-член ".BuildEvents" в Connect.

Пример:

private _BuildEvents _buildEvents;

public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
              {
                _buildEvents = _applicationObject.Events.BuildEvents;
              }

Затем подключите обработчики событий к

this._buildEvents

а не

_applicationObject.Events.BuildEvents

где приложение _applicationObject = (EnvDTE.DTE);

Стоит попробовать хотя бы, ИМХО.