Reputation: 13842
I am converting a VS Addin to a VS Package.
I have this code in my VSIX Package class(that derives from Microsoft.VisualStudio.Shell.Package)
protected override void Initialize() {
base.Initialize();
var dte = this.GetService<DTE>() as DTE2;
if(dte != null) {
var x = dte.MainWindow;
However calling dte.MainWindow
in this context throws a NullReferenceException
.
Something must not be initialized then. When am I supposed to call dte.MainWindow
then?
In the VS Addin it was working when dte.MainWindow
was called from public void OnStartupComplete(ref Array custom) {
in the Connect
Addin type.
Upvotes: 1
Views: 379
Reputation: 13842
To be able to call dte.MainWindow
I found the option to register to event dte.Events.DTEEvents.OnStartupComplete
. As explained here, I need to keep a reference to the DTEEvents
object to avoid getting it discarded.
DTEEvents m_EventsObj;
protected override void Initialize() {
base.Initialize();
var dte = this.GetService<DTE>() as DTE2;
if(dte != null) {
m_EventsObj = dte.Events.DTEEvents;
m_EventsObj.OnStartupComplete += delegate {
var mainWindow = dte.MainWindow; // <-- it works!!
...
};
Upvotes: 1
Reputation: 4414
I have also seen that issue when DTE is not null but DTE.MainWindow is null if called when initializing my MZ-Tools package. I have pending to reproduce it with a minimal package (a quick attempt a few days ago was not able to reproduce it).
I have also seen an InvalidCastException when getting DTE.MainWindow when terminating the package, which I have also to reproduce:
private WindowEx GetMainWindowEx()
{
EnvDTE.Window mainWindow = null;
WindowEx mainWindowEx = null;
try
{
mainWindow = m_dte.MainWindow;
}
catch (InvalidCastException)
{
// This can happen in the case of a package after the IDE is closed that needs to show a MessageBox
}
catch (NullReferenceException)
{
// This can happen in the case of a package loaded before the IDE is initialized that needs to show a MessageBox
}
if (mainWindow != null)
{
mainWindowEx = new WindowEx(m_plugIn, mainWindow);
}
return mainWindowEx;
}
In my case I only need the MainWindow to get its handle (hwnd) as parent for message boxes that in very rare cases must be shown during initialization/termination and if it fails I can use null as parent window.
Upvotes: 0