2010-05-10 11 views

Trả lời

13

Sự kiện OnBuildDone không thể cho bạn biết điều gì đã xảy ra. Một số dự án trong giải pháp có thể đã được xây dựng đúng cách, một số dự án thì không. Thay vào đó, bạn sẽ cần OnBuildProjConfigDone. Cháy cho từng dự án, đối số Success cho bạn biết nếu nó hoạt động.

+0

Trong trường hợp của tôi, OnBuildDone không bao giờ bị sa thải, nhưng OnBuildProjConfigDone hoạt động ok –

+0

@DinisCruz Đôi khi OnBuildDone không kích hoạt nếu bạn không giữ tham chiếu đến dte.Events.BuildEvents – Artiom

+1

Có một mẫu mã đầy đủ về cách thực hiện việc này tại đây: https://github.com/edsykes/VisualStudioBuildEvents –

6

Thông thường, bạn cần xử lý nhiều dự án đang được xây dựng. Đây có thể là một giải pháp xây dựng, hoặc xây dựng một dự án phụ thuộc vào một dự án khác.

Vì vậy, để tìm ra khi một xây dựng thành công đã kết thúc, bạn cần phải sử dụng một sự kết hợp của hai xây dựng sự kiện:

OnBuildProjConfigDone và OnBuildDone.

Bạn cũng sẽ cần biến thành viên để theo dõi trạng thái tổng thể xây dựng.

Trình xử lý OnBuildProjConfigDone của bạn sẽ được gọi cho từng dự án được xây dựng và nó được chuyển qua một bool để cho bạn biết liệu dự án đó có thành công hay không. Gán kết quả này cho biến thành viên của bạn để theo dõi trạng thái tổng thể.

Cuối cùng, trình xử lý OnBuildDone của bạn sẽ được gọi. Tại đây, bạn có thể xem xét biến thành viên của mình để xem có bất kỳ dự án xây dựng nào không thành công.

Dưới đây là một số mã ví dụ từ tiện ích mở rộng tôi đã viết cho VS2012. Phần mở rộng cung cấp một lệnh "xây dựng tùy chỉnh" để xây dựng dự án đang hoạt động và khởi chạy trình gỡ rối nếu việc xây dựng thành công.

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" là gì? Tôi đang ở trên VS2010, có thể là một mục cụ thể năm 2012? – granadaCoder

+0

GetGlobalService là một phương thức trên Microsoft.VisualStudio.Shell.Package, mà phần mở rộng của tôi phân lớp. – ryanman

2

Dành cho độc giả trong tương lai, hãy xem bài viết này.

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

và/hoặc

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

Về cơ bản, có thể có một lỗi. Công việc xung quanh là đặt biến thành viên của ".BuildEvents" trên Kết nối.

Ví dụ:

private _BuildEvents _buildEvents; 

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

Sau đó cấp điện cho xử lý sự kiện để

this._buildEvents 

và không

_applicationObject.Events.BuildEvents 

nơi _applicationObject = (EnvDTE.DTE) ứng dụng;

Nó đáng để thử ít nhất, IMHO.

+0

Chụp. Bây giờ tôi đã viết ở trên, tôi tìm thấy một phản ứng SOF rất tốt. http://stackoverflow.com/questions/14165885/add-in-events-are-never-executed – granadaCoder