3

In some extension we implement the IVsUpdateSolutionEvents2 and IVsSolutionBuildManager2 used for registering caller with the AdviseUpdateSolutionEvents

For example, this called before any build actions have begun:

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

However, also need getting the status or type of the current build action, for example: build/rebuild/clean/deploy

Available & known variants:

BuildEvents

With the Events.BuildEvents i can subscribe to OnBuildBegin, for example:

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

and use the buildType in any places, because the vsBuildAction provides all the necessary information

but the UpdateSolution_Begin / UpdateSolution_StartUpdate called first as priority with advising method, and as result the buildType sets too late..

also we can use this OnBuildBegin instead of UpdateProjectCfg_Begin / UpdateSolution_StartUpdate, but our handling is also needed as soon as possible with priority caller

IVsUpdateSolutionEvents4

The IVsUpdateSolutionEvents4.UpdateSolution_BeginUpdateAction provides the dwAction and fired before every update action begins during solution build - before the first UpdateProjectCfg_Begin

it's exactly what i need! because dwAction i can check with the VSSOLNBUILDUPDATEFLAGS

However :( it appeared in VS2012, our extension supports the VS2010 and higher... so need also variant for 2010 version

UpdateProjectCfg_Begin

The IVsUpdateSolutionEvents2.UpdateProjectCfg_Begin also provides the dwAction (see also VSSOLNBUILDUPDATEFLAGS) and available for 2010 version, however it's the same as first BuildEvents variant - it's too late for handling (and not quite suitable for our task)

Question

I can't find documentation for this, however the VSSOLNBUILDUPDATEFLAGS available for VS2010, so i think should be variant for getting this as current state of the build action, e.g as with __VSHPROPID and GetProperty for IVsHierarchy etc...

is it possible ? or i can only with OnBuildBegin subscription o_O


upd1:

__VSHPROPID4

found with \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;

so, looked doc. - BSTR __VSHPROPID4.VSHPROPID_BuildAction - retrieves the build action for an item

ok, good news, next step... try to get, for example:

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

where hr is a, for example:

IVsSolutionBuildManager2 sbm = (IVsSolutionBuildManager2)ServiceProvider.GlobalProvider.GetService(typeof(SVsSolutionBuildManager));

IVsHierarchy hr = null;
sbm.get_StartupProject(out hr);

However, the type always is null... it may be problem with notifying(has not occurred), but also similar result if used the pHierProj from UpdateProjectCfg_Begin / UpdateProjectCfg_Done:

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)

which already provides the dwAction...

and., how to use VSHPROPID_BuildAction -_- problem with IVsHierarchy ?

Denis Kuzmin
  • 800
  • 7
  • 14
  • Just checking: half of the time when people are trying to hook into Visual Studio build information, what they _really_ want to do is hook into MSBuild directly to extend their build system. What is the ultimate goal you're trying to achieve? – Jason Malinowski Nov 19 '14 at 16:32
  • @JasonMalinowski see [here](https://visualstudiogallery.msdn.microsoft.com/0d1dbfd7-ed8a-40af-ae39-281bfeca2334/) - *planned the context of build action for next version* – Denis Kuzmin Nov 19 '14 at 16:39

1 Answers1

3

finished :)

Solution 1

CommandEvents

With the EnvDTE.CommandEvents, we can work before processing IVsUpdateSolutionEvents2 and listen all incoming commands, sample:

...

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    
...

for example:

_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);
        }

});

Now we can work with type of action in UpdateSolution_Begin, for example:

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

...

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

etc.

full example you can see in sources (see comment where). Also, i think it’s not best variant, however it's variant for VS2010 and higher versions (also should work on very older 2005 & 2008, i think)…

For VS2012 and newer i recommend the IVsUpdateSolutionEvents4

So, my problem solved.

Other best variants ?

Denis Kuzmin
  • 800
  • 7
  • 14