本文介绍了使用 EnvDTE 自动化 Visual Studio的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下代码成功实例化/自动化 Visual Studio:

I am successfully instantiating/automating Visual Studio using the following code:

System.Type t = System.Type.GetTypeFromProgID("VisualStudio.DTE.9.0");
object obj = Activator.CreateInstance(t, true);
dte = (DTE)obj;
Solution sln = dte.Solution;
sln.Open(SolutionFile);
System.Threading.Thread.Sleep(1000);
//Do stuff with the solution

注意到 Thread.Sleep(1000) 调用了吗?如果我不包括它,代码会尝试在实例准备好之前对其进行错误处理,并且我会收到一个异常:

Notice the Thread.Sleep(1000) call? If I don't include that, the code tries to bug the instance before it's ready and I get an exception:

the message filter indicated that the application is busy.

有没有办法轮询这个对象以准备就绪,而不是恰好等待 n 秒?

Rather than wait exactly n seconds, is there a way to poll this object for readiness?

推荐答案

作为此问题的解决方案,您可以注册一个事件,该事件在解决方案加载完成时发出通知.

As a solution to this issue you can register to an event that notifies when the solution load is done.

这是一个类示例,可让您侦听解决方案加载时的事件:

This is a sample of class that lets you listen to events on solution loading:

public class SolutionEventsListener : IVsSolutionEvents, IDisposable
{
    private IVsSolution solution;
    private uint solutionEventsCookie;

    public event Action AfterSolutionLoaded;
    public event Action BeforeSolutionClosed;

    public SolutionEventsListener(IServiceProvider serviceProvider)
    {
        InitNullEvents();

        solution = serviceProvider.GetService(typeof (SVsSolution)) as IVsSolution;
        if (solution != null)
        {
            solution.AdviseSolutionEvents(this, out solutionEventsCookie);
        }
    }

    private void InitNullEvents()
    {
        AfterSolutionLoaded += () => { };
        BeforeSolutionClosed += () => { };
    }

    #region IVsSolutionEvents Members

    int IVsSolutionEvents.OnAfterCloseSolution(object pUnkReserved)
    {
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnAfterLoadProject(IVsHierarchy pStubHierarchy, IVsHierarchy pRealHierarchy)
    {
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
    {
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnAfterOpenSolution(object pUnkReserved, int fNewSolution)
    {
        AfterSolutionLoaded();
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved)
    {
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnBeforeCloseSolution(object pUnkReserved)
    {
        BeforeSolutionClosed();
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnBeforeUnloadProject(IVsHierarchy pRealHierarchy, IVsHierarchy pStubHierarchy)
    {
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnQueryCloseProject(IVsHierarchy pHierarchy, int fRemoving, ref int pfCancel)
    {
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnQueryCloseSolution(object pUnkReserved, ref int pfCancel)
    {
        return VSConstants.S_OK;
    }

    int IVsSolutionEvents.OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel)
    {
        return VSConstants.S_OK;
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        if (solution != null && solutionEventsCookie != 0)
        {
            GC.SuppressFinalize(this);
            solution.UnadviseSolutionEvents(solutionEventsCookie);
            AfterSolutionLoaded = null;
            BeforeSolutionClosed = null;
            solutionEventsCookie = 0;
            solution = null;
        }
    }

    #endregion
}

使用示例:

DTE2 applicationObject = dte;
var serviceProvider = new ServiceProvider(applicationObject as IServiceProvider);
solutionEventsListener = new SolutionEventsListener(serviceProvider);
solutionEventsListener.AfterSolutionLoaded += () => /* logic here */ ;

这篇关于使用 EnvDTE 自动化 Visual Studio的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 05:38
查看更多