VS 2005/2013/2015/2017/2019 解决方案构建计时器
适用于 VS2005、VS2013/2015 和 VS2017/2019 的附加组件,用于显示构建完整解决方案所需的时间。
- 下载 SolutionBuildTimer2019 - 40 KB
- 下载 SolutionBuildTimer2013 - 19.2 KB
- 下载 SolutionBuildTimer - 277.6 KB
背景
我最近发现一篇博客文章,提到了 Visual Studio 2005 C++ 解决方案中一个未公开的开关(/MP),它可以多线程编译源文件。
我想确定在我的 30 个项目解决方案中能节省多少时间,因此需要分别用和不用该开关来计时解决方案构建。不幸的是,允许你启用构建时间的 VS2005 C++ 项目设置不会计时整个解决方案,只会计时每个单独项目的构建时间。在用秒表进行了两次构建来确定总构建时间后(记录在案:不用开关是 28 分 26 秒,用了是 17 分 42 秒),我开始寻找一种方法让 IDE 告诉我总构建时间。
在 Google 上搜索这个问题,我找到了其他博客和论坛帖子,人们都在抱怨缺少此功能(这在 Visual Studio 6 时代是存在的)。
我的解决方案是使用 Visual Studio 2005 中提供的 IDE 自动化功能来添加回这个非常受欢迎的功能。
代码工作原理
该附加组件最初是使用 Visual Studio 2005 C# 附加组件向导生成的。这创建了可以挂载其余代码的框架。
IDE 自动化模型公开了两个事件,OnBuildBegin
和 OnBuildDone
,它们非常适合用在附加组件中,因为它们在构建开始和结束时触发。
在附加组件的 OnConnection
事件中,我们获取我们打算向其发送输出的窗口窗格(在本例中为“生成”窗口),并将我们自己的事件处理程序添加到 IDE。
public void OnConnection(object application, ext_ConnectMode connectMode,
object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
// We want our output in the Build window
OutputWindow outputWindow =
(OutputWindow)_applicationObject.Windows.Item(Constants.vsWindowKindOutput).Object;
outputWindowPane = outputWindow.OutputWindowPanes.Item("Build");
// Add ourselves as a OnBuildBegin/OnBuildDone handler
EnvDTE.Events events = _applicationObject.Events;
buildEvents = (EnvDTE.BuildEvents)events.BuildEvents;
buildEvents.OnBuildBegin +=
new _dispBuildEvents_OnBuildBeginEventHandler(this.OnBuildBegin);
buildEvents.OnBuildDone +=
new _dispBuildEvents_OnBuildDoneEventHandler(this.OnBuildDone);
}
在附加组件的 OnDisconnection
事件中,我们清理自身。
public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
{
// Remove ourselves as a OnBuildBegin/OnBuildEnd handler
if (buildEvents != null)
{
buildEvents.OnBuildBegin -=
new _dispBuildEvents_OnBuildBeginEventHandler(this.OnBuildBegin);
buildEvents.OnBuildDone -=
new _dispBuildEvents_OnBuildDoneEventHandler(this.OnBuildDone);
}
}
附加组件的核心部分在于我们在 OnConnection
事件中添加的处理程序。首先是 OnBuildBegin
事件。
public void OnBuildBegin(EnvDTE.vsBuildScope Scope, EnvDTE.vsBuildAction Action)
{
// Check for a solution build for Build or RebuildAll
if (EnvDTE.vsBuildScope.vsBuildScopeSolution == Scope &&
(EnvDTE.vsBuildAction.vsBuildActionBuild == Action ||
EnvDTE.vsBuildAction.vsBuildActionRebuildAll == Action))
{
// Flag our build timer
amTiming = true;
dtStart = DateTime.Now;
outputWindowPane.OutputString(String.Format(
"Starting timed solution build on {0}\n", dtStart));
}
}
OnBuildBegin
事件首先检查我们是否正在构建解决方案(而不是项目),并进一步将我们的计时限制在**生成**或**重新生成所有**命令(我们想要忽略“清理”命令)。如果检查成功,我们然后设置一个标志来说明我们正在计时构建,获取当前日期和时间,并将它们发送到“生成”窗口。
其次是 OnBuildDone
事件。
public void OnBuildDone(EnvDTE.vsBuildScope Scope, EnvDTE.vsBuildAction Action)
{
// Check if we are actually timing this build
if (amTiming)
{
amTiming = false;
dtEnd = DateTime.Now;
outputWindowPane.OutputString(String.Format(
"Ended timed solution build on {0}\n", dtEnd));
TimeSpan tsElapsed = dtEnd - dtStart;
outputWindowPane.OutputString(String.Format("Total build time: {0}\n",
tsElapsed));
}
}
OnBuildDone
事件首先检查我们是否确实正在计时构建。如果正确,我们然后获取当前日期和时间,将其发送到“生成”窗口,计算构建开始和结束之间经过的时间,最后将其发送到“生成”窗口。
关注点
我发现很难确定 IDE 中可用的自动化功能。关于这方面的 MSDN 帮助对于刚开始接触附加组件的人来说似乎非常缺乏(这只是我的第三个)。
我确实在 VS2005 自动化示例(可从 Microsoft 网站下载)中找到一个非常有用的资源,一旦我能浏览源代码,它就给了我所有需要的入口点。
Visual Studio 2013
当 Visual Studio 2013 发布时,我注意到现在有一个选项可以为 C++ 解决方案启用构建计时(**工具** > **选项** > **项目和解决方案** > **VC++ 项目设置** > **构建计时**)。
我立即启用了此选项,并发现 IDE 开发人员在计时输出中提供的细节过于冗余。我仍然更喜欢我最初的 Solution Build Timer 的输出,所以想在 VS2013 中启用它。
Microsoft 引入了 VSPackages 来代替 Add Ins,所以我创建了一个新的 VS2013 包并将原始代码迁移过去。
结果可下载为 _SolutionBuildTimer2013.zip_。这包含扩展的源代码以及一个 vsix 包,你可以只需双击该文件即可安装。
Visual Studio 2015
安装 2015 并尝试在 VS2015 中重新构建我的扩展后,我发现 2013 版本也可以构建为支持 2015。源代码和 vsix 包已相应更新。
Visual Studio 2017
Visual Studio 2017 更改了 VSIX 格式,这意味着我必须再次重新构建我的扩展才能支持此版本。
Visual Studio 2019
通过简单地更改 VSIX 的清单目标版本,添加了对 Visual Studio 2019 的支持。
VSIX 更改
扩展的 2017/2019 版本已更新为支持异步加载,这是 VS2019 所必需的。
历史
- 2019 年 6 月 5 日:初始版本