TestExecWindow
 All Modules Pages
Class TestExecWindowPackage - Visual Studio integration, enabling DTE access

Overview:

Visual Studio integration by deriving from base class 'AsyncPackage'

Base class "AsyncPackage" implements the required interface IVsPackage which cares for proper integration with Visual Studio:

public sealed class TestExecWindowPackage : AsyncPackage

Getting acess to DTE

Microsoft Visual Studio allows programmatic access via a special environment, the "DTE" (= development tools environment). The "DTE object" is the root of the automation model for Visual Studio.

To get access to DTE object you can establish a connection within the package class of your C# assembly. The reference to the DTE object can be distributed within your application classes as needed.

First you have to define appropriate data:

private EnvDTE80.DTE2 dte; // access to the DTE object
private DteInitializer dteInitializer; // supports delayed DTE initialization

Request for the DTE object is done within the custom method InitializeDTE:

private void InitializeDTE()
{
Debug.WriteLine("InitializeDTE-Begin");
// Request access to DTE object
this.dte = this.GetService(typeof(Microsoft.VisualStudio.Shell.Interop.SDTE))
as EnvDTE80.DTE2;
// Pass DTE reference to static data members of other classes
// which also need access to DTE
Executor.dte = this.dte;
VisualStudioConnector.dte = this.dte;
if (this.dte == null) // the IDE is not yet fully initialized
{
Debug.WriteLine("InitializeDTE: DTE is not yet fully initialized");
// Prepare for delayed initialization of DTE. The instantiated
// DteInitializer class will register for notifications by
// Visual Studio, check for full initialization of DTE and
// finally call the given callback (=InitializeDTE, i.e. this method)
// when DTE becomes available.
IVsShell shellService;
shellService = this.GetService(typeof(SVsShell)) as IVsShell;
this.dteInitializer = new DteInitializer(shellService, this.InitializeDTE);
}
else
{
Debug.WriteLine("InitializeDTE: DTE is set");
this.dteInitializer = null;
}
Debug.WriteLine("InitializeDTE-End");
}

The call of InitializeDTE is done within overridden base method InitializeAsync:

/// Initialization of the package; this method is called asynchronously by Visual Studio.
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<Microsoft.VisualStudio.Shell.ServiceProgressData> progress)
{
// Do something on background task
// ...
await Task.Delay(5000);
// Now switch to UI thread
// Switches to the UI thread in order to consume some services used in command initialization
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
// Synchronous initialization on UI thread
TestExecWindowCommand.Initialize(this);
base.Initialize();
InitializeDTE();
}