【发布时间】:2010-05-10 10:44:44
【问题描述】:
我正在编写一个 VS 插件,我需要在构建成功后运行某个方法。
我尝试过使用dte.Events.BuildEvents.OnBuildDone,但即使构建失败也会发生该事件。
是否有我应该使用的属性或其他事件?
【问题讨论】:
标签: visual-studio build add-in envdte
我正在编写一个 VS 插件,我需要在构建成功后运行某个方法。
我尝试过使用dte.Events.BuildEvents.OnBuildDone,但即使构建失败也会发生该事件。
是否有我应该使用的属性或其他事件?
【问题讨论】:
标签: visual-studio build add-in envdte
OnBuildDone 事件无法告诉您发生了什么。解决方案中的某些项目可能已正确构建,而有些则没有。您将需要 OnBuildProjConfigDone 代替。为每个项目触发,Success 参数告诉你它是否有效。
【讨论】:
通常,您需要处理正在构建的多个项目。这可能是一个解决方案构建,或者构建一个依赖于另一个项目的项目。
因此,要确定成功构建何时完成,您需要结合使用两个构建事件:
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);
}
【讨论】:
对于未来的读者,请查看这篇文章。
和/或
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)应用程序;
至少值得一试,恕我直言。
【讨论】: