Visual Studio的当前构建操作类型 – Microsoft.VisualStudio.Shell.Interop

在某些扩展中,我们实现了用于使用AdviseUpdateSolutionEvents注册调用者的IVsUpdateSolutionEvents2和IVsSolutionBuildManager2

例如,在任何构建操作开始之前调用此方法:

public int UpdateSolution_Begin(ref int pfCancelUpdate) { ... } 

但是,还需要获取当前构建操作的状态或类型,例如:build / rebuild / clean / deploy

可用和已知的变体:

BuildEvents

使用Events.BuildEvents,我可以订阅OnBuildBegin,例如:

 _buildEvents.OnBuildBegin += new _dispBuildEvents_OnBuildBeginEventHandler((vsBuildScope Scope, vsBuildAction Action) => { buildType = (BuildType)Action; }); 

并在任何地方使用buildType,因为vsBuildAction提供了所有必要的信息

但是UpdateSolution_Begin / UpdateSolution_StartUpdate首先作为优先级使用advising方法调用,因此buildType设置太晚了..

我们也可以使用这个OnBuildBegin而不是UpdateProjectCfg_Begin / UpdateSolution_StartUpdate,但是我们的处理也需要尽快与优先调用者一起使用

IVsUpdateSolutionEvents4

IVsUpdateSolutionEvents4.UpdateSolution_BeginUpdateAction提供dwAction并在解决方案构建期间每个更新操作开始之前触发 – 在第一个UpdateProjectCfg_Begin之前

这正是我需要的! 因为dwAction我可以用VSSOLNBUILDUPDATEFLAGS查看

但是:(它出现在VS2012,我们的扩展支持VS2010和更高……所以也需要2010版本的变种

UpdateProjectCfg_Begin

IVsUpdateSolutionEvents2.UpdateProjectCfg_Begin还提供dwAction(参见VSSOLNBUILDUPDATEFLAGS )并可用于2010版本,但它与第一​​个BuildEvents变体相同 – 处理时间太晚(并且不太适合我们的任务)

我找不到这方面的文档,但VSSOL可以为VS2010提供VSSOLNBUILDUPDATEFLAGS ,所以我认为应该是将其作为构建操作的当前状态的变体,例如,对于IVsHierarchy等__VSHPROPID和GetProperty …

可能吗 ? 或者我只能使用OnBuildBegin订阅o_O


upd1:

__VSHPROPID4

找到\ VisualStudioIntegration \ Common \ Inc \ vsshell100.h:

 enum __VSHPROPID4 { VSHPROPID_TargetFrameworkMoniker = -2102, VSHPROPID_ExternalItem = -2103, VSHPROPID_SupportsAspNetIntegration = -2104, VSHPROPID_DesignTimeDependencies = -2105, VSHPROPID_BuildDependencies = -2106, VSHPROPID_BuildAction = -2107, VSHPROPID_DescriptiveName = -2108, VSHPROPID_AlwaysBuildOnDebugLaunch = -2109, VSHPROPID_FIRST4 = -2109 } ; typedef /* [public] */ DWORD VSHPROPID4; 

所以,看着doc。 – BSTR __VSHPROPID4.VSHPROPID_BuildAction – 检索项目的构建操作

好的,好消息,下一步…试着去,例如:

 object type; hr.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID4.VSHPROPID_BuildAction, out type); 

其中hr是a,例如:

 IVsSolutionBuildManager2 sbm = (IVsSolutionBuildManager2)ServiceProvider.GlobalProvider.GetService(typeof(SVsSolutionBuildManager)); IVsHierarchy hr = null; sbm.get_StartupProject(out hr); 

但是,类型总是为空…它可能是通知(尚未发生)的问题,但如果使用来自UpdateProjectCfg_Begin / UpdateProjectCfg_Done的pHierProj,也会出现类似的结果:

 int UpdateProjectCfg_Begin(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, ref int pfCancel) int UpdateProjectCfg_Done(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, int fSuccess, int fCancel) 

已经提供了dwAction ……

和。,如何在IVsHierarchy中使用VSHPROPID_BuildAction -_-问题?

完了:)

解决方案1

CommandEvents

使用EnvDTE.CommandEvents ,我们可以在处理IVsUpdateSolutionEvents2并监听所有传入命令之前工作,示例:

 GUID: {5EFC7975-14BC-11CF-9B2B-00AA00573819} (ID: 882) :: Build.BuildSolution GUID: {5EFC7975-14BC-11CF-9B2B-00AA00573819} (ID: 883) :: Build.RebuildSolution GUID: {5EFC7975-14BC-11CF-9B2B-00AA00573819} (ID: 884) :: Build.DeploySolution GUID: {5EFC7975-14BC-11CF-9B2B-00AA00573819} (ID: 885) :: Build.CleanSolution GUID: {1496A755-94DE-11D0-8C3F-00C04FC2AAE2} (ID: 2005) :: Build.PublishSelection GUID: {1496A755-94DE-11D0-8C3F-00C04FC2AAE2} (ID: 353) :: Build.Link ... 

例如:

 _cmdEvents.BeforeExecute += new _dispCommandEvents_BeforeExecuteEventHandler((string guid, int id, object customIn, object customOut, ref bool cancelDefault) => { if(GuidList.VSStd97CmdID == guid || GuidList.VSStd2KCmdID == guid) { _c.updateContext((BuildType)id); } }); 

现在我们可以使用UpdateSolution_Begin中的操作类型,例如:

 if(evt.BuildType != BuildType.Common && evt.BuildType != buildType) { //... } 

 if(buildType == BuildType.Clean || buildType == BuildType.LinkOnly){ //... } 

等等

你可以在资源中看到完整的例子(见评论在哪里) 。 此外,我认为它不是最好的变种,但它是VS2010和更高版本的变体(也应该适用于非常大的2005年和2008年,我认为)…

对于VS2012及更新版本,我推荐使用IVsUpdateSolutionEvents4

所以,我的问题解决了。

其他最好的变种?