簡體   English   中英

在Visual Studio 2015中捕獲解決方案事件

[英]Capture solution events in Visual Studio 2015

我正在開發Visual Studio插件。 我想記錄一下打開新解決方案的事件。 為了實現這一點,我實現了IVsSolutionEvents接口,並使用AdviseSolutionEvents()注冊了它。 但是,當我運行VS的測試實例並打開解決方案時,沒有調用正確的事件方法。

這是我的代碼:

public sealed class MyPackage : Package, IVsSolutionEvents
{
        // ...

        protected override void Initialize()
        {
            base.Initialize();

            IVsSolution solution = GetService(typeof(SVsSolution)) as IVsSolution;
            uint cookie = 0;
            solution.AdviseSolutionEvents(this, out cookie);
        }

        // ...  

        public int OnAfterOpenSolution(object pUnkReserved, int fNewSolution)
        {
            MessageBox.Show("Opened a solution!");
            return VSConstants.S_OK;
        }
}

為什么從不調用OnAfterOpenSolution()

好,我知道了。

事實證明,默認情況下,Visual Studio軟件包在啟動時不會加載,以避免消耗內存和CPU。 而是,Visual Studio在需要時加載它們。 因此,事件之前未注冊。

要更改此行為,必須在類定義中添加ProvideAutoLoad屬性:

[ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)]
public sealed class Command1Package : Package 
...

該屬性的值是一個字符串,帶有Guid標識UI上下文,例如,未打開任何解決方案的上下文。

資源

您是否曾在2015年使用Microsoft.VisualStudio.Shell.Interop命名空間中的IVsSolutionEvents2接口嘗試過此操作?

不用理會,此方法在您使用的界面上。

您的實現是什么樣的?

這是一個通過抽象類實現的示例:

   [CLSCompliant(false)]
    public abstract class SolutionListener : IVsSolutionEvents, IVsSolutionEvents2, IVsSolutionEvents3, IVsSolutionEvents4, IDisposable
    {
        public IServiceProvider ServiceProvider { get; private set; }

        public IVsSolution Solution { get; private set; }

        private uint eventsCookie = (uint)ShellConstants.VSCOOKIE_NIL;
        private bool isDisposed;
        private static volatile object Mutex = new object();

        protected SolutionListener(IServiceProvider serviceProvider)
        {
            ServiceProvider = serviceProvider;

            Solution = serviceProvider.GetService(typeof(SVsSolution)) as IVsSolution;
            Debug.Assert(Solution != null, "Could not get the IVsSolution object");
            if (Solution == null)
            {
                throw new InvalidOperationException();
            }
        }

        public abstract int OnAfterCloseSolution(object reserved);
        public abstract int OnAfterClosingChildren(IVsHierarchy hierarchy);
        public abstract int OnAfterLoadProject(IVsHierarchy stubHierarchy, IVsHierarchy realHierarchy);
        public abstract int OnAfterMergeSolution(object pUnkReserved);
        public abstract int OnAfterOpenProject(IVsHierarchy hierarchy, int added);
        public abstract int OnAfterOpenSolution(object pUnkReserved, int fNewSolution);
        public abstract int OnAfterOpeningChildren(IVsHierarchy hierarchy);
        public abstract int OnBeforeCloseProject(IVsHierarchy hierarchy, int removed);
        public abstract int OnBeforeCloseSolution(object pUnkReserved);
        public abstract int OnBeforeClosingChildren(IVsHierarchy hierarchy);
        public abstract int OnBeforeOpeningChildren(IVsHierarchy hierarchy);
        public abstract int OnBeforeUnloadProject(IVsHierarchy realHierarchy, IVsHierarchy rtubHierarchy);
        public abstract int OnQueryCloseProject(IVsHierarchy hierarchy, int removing, ref int cancel);
        public abstract int OnQueryCloseSolution(object pUnkReserved, ref int cancel);
        public abstract int OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int cancel);
        public abstract int OnAfterAsynchOpenProject(IVsHierarchy hierarchy, int added);
        public abstract int OnAfterChangeProjectParent(IVsHierarchy hierarchy);
        public abstract int OnAfterRenameProject(IVsHierarchy hierarchy);
        public abstract int OnQueryChangeProjectParent(IVsHierarchy hierarchy, IVsHierarchy newParentHier, ref int cancel);

        public virtual void Initialize()
        {
            if (Solution != null && eventsCookie == (uint)ShellConstants.VSCOOKIE_NIL)
            {
                ErrorHandler.ThrowOnFailure(Solution.AdviseSolutionEvents(this, out eventsCookie));
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!isDisposed)
            {
                lock (Mutex)
                {
                    if (disposing && Solution != null && eventsCookie != (uint)ShellConstants.VSCOOKIE_NIL)
                    {
                        ErrorHandler.ThrowOnFailure(Solution.UnadviseSolutionEvents((uint)eventsCookie));
                        eventsCookie = (uint)ShellConstants.VSCOOKIE_NIL;
                    }
                    isDisposed = true;
                }
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM