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并监听所有传入命令之前工作,示例:
-
VSStd97CmdID – {5EFC7975-14BC-11CF-9B2B-00AA00573819} http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.vsconstants.vsstd97cmdid.aspx
-
VSStd2KCmdID – {1496A755-94DE-11D0-8C3F-00C04FC2AAE2} http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.vsconstants.vsstd2kcmdid.aspx
…
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
所以,我的问题解决了。
其他最好的变种?