You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:04:56