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);
}
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 –
@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
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 –