2010-05-10 85 views
10

我正在写一个VS加载项,我需要在成功构建之后运行某个方法。 我试过使用dte.Events.BuildEvents.OnBuildDone,但即使构建失败,该事件也会发生。成功构建完成后如何获取通知?

是否有财产或其他事件我应该使用?

回答

13

OnBuildDone事件不能告诉你发生了什么。解决方案中的一些项目可能已经正确构建,有些则没有。您需要改用OnBuildProjConfigDone。为每个项目着火,Success论述告诉你它是否工作。

+0

在我的情况下,OnBuildDone从未解雇,但OnBuildProjConfigDone工作正常 – 2012-07-30 17:13:23

+0

@DinisCruz有时,如果您不持有对dte.Events的引用,则OnBuildDone不会触发。BuildEvents – Artiom 2014-01-10 13:43:08

+1

这里有一个完整的代码示例:https://github.com/edsykes/VisualStudioBuildEvents – 2014-03-27 14:40:28

6

通常,您需要处理多个正在构建的项目。这可能是解决方案构建,或者构建依赖于另一个项目的项目。

所以,弄清楚当一个成功的构建完成后,您需要使用两个构建事件的组合:

OnBuildProjConfigDone和OnBuildDone。

您还需要一个成员变量来跟踪整体构建状态。

您的OnBuildProjConfigDone处理程序将为每个构建的项目调用,并且它会传递一个布尔值来告诉您该项目构建是否成功。将此结果分配给您的成员变量以跟踪整体状态。

最后,你的OnBuildDone处理函数会被调用。在这里,你可以看看你的成员变量,看看是否有任何项目构建失败。

以下是我为VS2012编写的扩展的一些示例代码。该扩展提供了一个“定制构建”命令,用于构建活动项目并在构建成功时启动调试器。

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); 
} 
+0

什么是“GetGlobalService”?我在VS2010上,也许是2012年的特定项目? – granadaCoder 2013-09-11 19:12:58

+0

GetGlobalService是Microsoft.VisualStudio.Shell.Package上的一个方法,它是我的扩展的子类。 – ryanman 2013-09-12 15:41:55

2

对于未来的读者,请看看这篇文章。

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

基本上,有可能是一个错误。 解决方法是在Connect上设置“.BuildEvents”的成员变量。

实施例:

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)应用程序;

这是值得一试,至少,恕我直言。

+0

拍摄。现在我写了上面的内容,我发现了一个非常好的SOF响应。 http://stackoverflow.com/questions/14165885/add-in-events-are-never-executed – granadaCoder 2013-09-11 19:40:07