我正在将VS Addin转换为VS包。
我的VSIX Package类中有这个代码(派生自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
。
然后必须初始化某些东西。 我什么时候打电话给dte.MainWindow
?
在VS Addin中,当dte.MainWindow
Addin类型中的public void OnStartupComplete(ref Array custom) {
调用Connect
时,它正在运行。
答案 0 :(得分: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!!
...
};
答案 1 :(得分:0)
当DTE不为null但DTE.MainWindow在初始化我的MZ-Tools包时被调用时,我也看到了这个问题。我有待用最小的包重现它(几天前的快速尝试无法重现它)。
在终止程序包时获取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;
}
在我的情况下,我只需要MainWindow将其句柄(hwnd)作为消息框的父级,在极少数情况下必须在初始化/终止期间显示,如果失败,我可以使用null作为父窗口。