How to intercept project save event in visual studio 2017 sdk?

1.5k views Asked by At

It's possible to intercept the project save event in visual studio 2017 sdk?

UPDATE

I'm currently developing an extension of visual studio 2017 where I need to know when any change is persisted.

Ex: When I add a new reference in the project (I know there are events for when the reference is added / changed / removed but did not meet my need), the project is marked as pending to be saved. I need to intercept it when it's saved (better if it is before saving).

I tried the Dte.Events.DocumentEvents.DocumentSaved event, but it is not triggered in the save project; DTE.Events.SolutionEvents and DTE.Events.SolutionItemEvents have no event of the type I need.

It is possible?

2

There are 2 answers

0
Eduardo Carísio On BEST ANSWER

The correct one in this case would be to use implement IVsRunningDocTableEvents3 overriding the OnBeforeSave method.

In this way, I know exactly when a project is to be saved and perform what it needs.

Ex.:

uint cookie;
var runningDocumentTable = (IVsRunningDocumentTable)GetGlobalService(typeof(SVsRunningDocumentTable));

runningDocumentTable.AdviseRunningDocTableEvents(new RunningDocTableEventsHandler(), out cookie);
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

namespace YourProject
{
    internal class RunningDocTableEventsHandler : IVsRunningDocTableEvents3
    {

        #region Methods

        public int OnAfterFirstDocumentLock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
        {
            return VSConstants.S_OK;
        }

        public int OnBeforeLastDocumentUnlock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
        {
            return VSConstants.S_OK;
        }

        public int OnAfterSave(uint docCookie)
        {
            return VSConstants.S_OK;
        }

        public int OnAfterAttributeChange(uint docCookie, uint grfAttribs)
        {
            return VSConstants.S_OK;
        }

        public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
        {
            return VSConstants.S_OK;
        }

        public int OnAfterDocumentWindowHide(uint docCookie, IVsWindowFrame pFrame)
        {
            return VSConstants.S_OK;
        }

        public int OnAfterAttributeChangeEx(uint docCookie, uint grfAttribs, IVsHierarchy pHierOld, uint itemidOld, string pszMkDocumentOld, IVsHierarchy pHierNew, uint itemidNew, string pszMkDocumentNew)
        {
            return VSConstants.S_OK;
        }

        public int OnBeforeSave(uint docCookie)
        {
            /////// MY CODE ////////
            return VSConstants.S_OK;
        }

        #endregion Methods
    }
}
2
Weiwei On

The DTE.Events.DocumentEvents works with opened project files, not entire project system. Each project loaded and displayed in the solution explorer is loaded by the project system for that project's type. So different version of project has its own project system implementation.

According to your requirement, you need to implement IVsSolutionEvents3 to be notified of a project being loaded/unloaded. And register that object as a listener in your package initialization code via the SVsSolutionBuildManager service.

Then implement IVsHierarchyEvents to be notified of project changes and Call AdviseHierarchyEvents on the IVsHierarchy object passed to the IVsSolutionEvents3's OnAfterProjectOpen implementation to register the event listener object.

More detailed explanation, please refer to below thread.

Visual Studio SDK - Handling File Add, Remove, and Rename Events