SSMS v19中ObjectExplorerService获取为null的问题求助
SSMS 19扩展获取ObjectExplorerService返回null的解决思路
我开发的SQL Server Management Studio(SSMS)扩展在SSMS 18.x版本中运行正常,但在SSMS 19版本中尝试获取ObjectExplorerService时始终返回null,触发System.NullReferenceException异常。使用的是.NET Framework 4.7.2,相关代码如下:
/// <summary> /// Initialization of the package; this method is called right after the package is sited, so this is the place /// where you can put all the initialization code that rely on services provided by VisualStudio. /// </summary> protected override void Initialize() { try { base.Initialize(); DefaultFolder = GetDefaultFolder(); Logger.LogFilePath = Path.Combine(DefaultFolder, "log.txt"); SetScriptsFolderCommand.Initialize(this); SetDefaultFolderCommand.Initialize(this); ObjectExplorerService explorerService = ServiceProvider.GlobalProvider.GetService(typeof(IObjectExplorerService)) as ObjectExplorerService; MenuContext = (ContextService)explorerService.Container.Components[0]; // System.NullReferenceException: 'Object reference not set to an instance of an object.' // (explorerService was null). ObjectBrowserMenuManager = new Managers.MenuManager(explorerService); ObjectBrowserMenuManager.Package = this; LoadScripts(); MenuContext.ObjectExplorerContext.CurrentContextChanged += new NodesChangedEventHandler(ObjectBrowserMenuManager.ObjectExplorerContext_CurrentContextChanged); } catch (Exception ex) { Logger.Error(ex); } }
以下是针对该问题的解决思路:
- 调整服务获取方式:SSMS 19重构了部分服务注入逻辑,全局
ServiceProvider.GlobalProvider可能无法正确获取到服务,改为通过包自身的ServiceProvider尝试获取:var explorerService = this.GetService(typeof(IObjectExplorerService)) as ObjectExplorerService; - 延迟初始化逻辑:SSMS 19中
ObjectExplorerService的初始化时机晚于包的Initialize方法,此时服务尚未完成注册。可以监听SSMS启动完成事件,在完全启动后再执行服务获取逻辑:var dte = this.GetService(typeof(DTE)) as DTE; dte.Events.DTEEvents.OnStartupComplete += () => { // 在此处获取ObjectExplorerService并执行后续初始化操作 }; - 避免依赖具体实现类:SSMS 19可能修改了
IObjectExplorerService的实现结构,优先获取接口实例而非直接转换为ObjectExplorerService具体类,减少对内部实现的依赖:var explorerService = this.GetService(typeof(IObjectExplorerService)); // 后续通过接口公开方法操作,不再依赖Container等内部属性 - 检查扩展兼容性配置:确认扩展的
.vsixmanifest文件中,SSMS版本范围是否包含19.x,同时验证目标框架声明是否匹配SSMS 19的要求(虽仍基于.NET Framework 4.7.2,但可能需要调整依赖声明)。 - 替换内部组件依赖:原代码中直接访问
explorerService.Container.Components[0]属于依赖未公开的内部实现细节,SSMS 19可能重构了这部分结构。建议使用官方公开API获取上下文服务,比如通过IObjectExplorerContext接口来获取当前上下文信息。
内容的提问来源于stack exchange,提问作者Wonk
相关产品推荐
相关产品推荐

