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

时间:2014-11-19 14:00:11

标签: c# visual-studio build visual-studio-extensions envdte

在某些扩展程序中,我们实施了IVsUpdateSolutionEvents2IVsSolutionBuildManager2用于使用AdviseUpdateSolutionEvents

注册来电者

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

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变体相同 - 处理起来太迟了(并不太适合我们的任务)

问题

我无法找到相关文档,但VSSOLNBUILDUPDATEFLAGS 可用于VS2010,所以我认为应该是将其作为构建操作的当前状态的变体,例如与__VSHPROPID和GetProperty for IVsHierarchy等...

有可能吗?或者我只能使用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 个答案:

答案 0 :(得分:2)

完成:)

解决方案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

所以,我的问题解决了。

其他最佳变体?