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
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.
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
}
Usage example:
DTE2 applicationObject = dte;
var serviceProvider = new ServiceProvider(applicationObject as IServiceProvider);
solutionEventsListener = new SolutionEventsListener(serviceProvider);
solutionEventsListener.AfterSolutionLoaded += () => /* logic here */ ;