2010-05-10 33 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

相關問題