2014-09-19 19 views
1

我將一個VS Addin轉換爲一個VS Package。爲什麼dte.MainWindow在VSIX Package Initialize方法中拋出一個NullRefEx?

我有我的VSIX包類代碼(從Microsoft.VisualStudio.Shell.Package派生)

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

    var dte = this.GetService<DTE>() as DTE2; 
    if(dte != null) { 
     var x = dte.MainWindow; 

但是呼籲在這方面dte.MainWindow拋出一個NullReferenceException

enter image description here

東西不能初始化。 我應該打電話給dte.MainWindow嗎?

在VS Addin中,當dte.MainWindowpublic void OnStartupComplete(ref Array custom) {調用Connect Addin類型時,它正在工作。

+0

Debug.Assert()讓你入睡。無論如何,它絕對沒有什麼可告訴你一些你不會很快找到的東西。這是有害的,刪除它。清理你的想法,你會看* dte *現在。 – 2014-09-19 17:55:13

+0

這個問題與Debug.Assert(...)Hans無關。順便說一句,它告訴我一些非常有用的東西:感謝這個斷言,我知道dte不是null,因此在調用get_MainWindow()期間NullRefEx來自null。 – 2014-09-19 18:01:53

+0

通往神祕問題的道路鋪平了假設。我們不知道的是_DEBUG條件是否被實際定義。一切都說它不是。 – 2014-09-19 18:09:50

回答

1

爲了能夠撥打dte.MainWindow我發現註冊到事件dte.Events.DTEEvents.OnStartupComplete的選項。正如here所解釋的那樣,我需要保留對DTEEvents對象的引用,以避免丟棄它。

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!! 
      ... 
     }; 
0

當DTE不爲空時,我也看到了這個問題,但如果在初始化我的MZ-Tools包時調用DTE.MainWindow爲null。我有待用最小的包來重現它(幾天前的一次快速嘗試未能重現它)。

越來越DTE.MainWindow時終止包,我也有重現的時候我還見過一個InvalidCastException:

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; 
    } 

在我來說,我只需要在主窗口得到它的句柄(HWND)作爲在非常罕見的情況下必須在初始化/終止期間顯示消息框的父代,如果失敗,我可以使用null作爲父窗口。

+1

我在打電話,所以我不能檢查自己,但是在VS不再處於殭屍狀態之後會發生嗎?例如您自己的http://www.mztools.com/articles/2013/MZ2013029.aspx – 2014-09-19 21:01:42

相關問題