3

This question is in reference to the SSMSAddinDenali SQL Server Management Studio 2012 Addin found here http://ssmsaddin2012.codeplex.com/SourceControl/changeset/view/19629#101185. I cannot implement IObjectExplorerService using .Net 4.0/4.5 while trying to build a SSMS 2012 addin. I would like to know if anyone can expose more info on connecting the to ObjectExplorerService; how to create a menu item in the database table context menu. I get this error (Unable to cast type Microsoft.SqlServer.Management.SqlStudio.Object.ObjectExplorerService to type Microsoft.SqlServer.Management.SqlStudio.Object.ContextService)


Important References that I needed to update just to get it to build :

Microsoft.SqlServer.Management.SDK.SqlStudio
C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\Microsoft.SqlServer.Management.Sdk.SqlStudio.dll Version 11.0.0.0

Microsoft.SqlServer.Management.SqlStudio.Explorer
C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\Extensions\Application\Microsoft.SqlServer.Management.SqlStudio.Explorer.dll Version 11.0.0.0

SqlPackageBase
C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\SqlPackageBase.dll Version 11.0.0.0

SqlManagerUI
C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\SQLManagerUI.dll Version 11.0.0.0

SqlWorkbench.Interfaces
C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\SqlWorkbench.Interfaces.dll Version 11.0.0.0


After I build my addin and run it in SSMS 2012 I get this error with my try catch with the code shown

SSMS 2012 Addin

Any further help would be greatly appreciated!

public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{


    //debug_message("OnConnection::");

    //_applicationDTE = (DTE)application;
    //_applicationObject = (DTE2)application;
    //_addInInstance = (AddIn)addInInst;
    //return;


    //if (connectMode == ext_ConnectMode.ext_cm_UISetup)
    //{
    //    object[] contextGUIDS = new object[] { };
    //    Commands2 commands = (Commands2)_applicationObject.Commands;
    //    string toolsMenuName = "Tools";

    //    //Place the command on the tools menu.
    //    //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
    //    Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];

    //    //Find the Tools command bar on the MenuBar command bar:
    //    CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
    //    CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;

    //    //This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in,
    //    //  just make sure you also update the QueryStatus/Exec method to include the new command names.
    //    try
    //    {
    //        //Add a command to the Commands collection:
    //        // add + (int)vsCommandStatus.vsCommandStatusEnabled if we want the default state to be enabled
    //        Command command = commands.AddNamedCommand2(_addInInstance, "FormatSQL", "Format SQL", "Executes the command for SSMSAddinDenali", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);

    //        //Add a control for the command to the tools menu:
    //        if ((command != null) && (toolsPopup != null))
    //        {
    //            command.AddControl(toolsPopup.CommandBar, 1);
    //        }
    //    }
    //    catch (System.ArgumentException)
    //    {
    //        //If we are here, then the exception is probably because a command with that name
    //        //  already exists. If so there is no need to recreate the command and we can 
    //        //  safely ignore the exception.
    //    }
    //}



    #region Object Explorer Context Event
    try
    {
        /* Microsoft.SqlServer.Management.UI.VSIntegration.ServiceCache
         * is from SqlPackageBase.dll and not from Microsoft.SqlServer.SqlTools.VSIntegration.dll
         * the code below just throws null exception if you have wrong reference */
        ObjectExplorerService objExplorerService;
        ContextService cs;
        NavigationService ns;


        objExplorerService = (ObjectExplorerService)ServiceCache.ServiceProvider.GetService(typeof(Microsoft.SqlServer.Management.UI.VSIntegration.ObjectExplorer.IObjectExplorerService));

        cs = (ContextService)objExplorerService.Container.Components[0];
        //cs.ObjectExplorerContext.CurrentContextChanged += new NodesChangedEventHandler(ObjectExplorerContext_CurrentContextChanged);
        //cs.UtilityExplorerContext.CurrentContextChanged += new NodesChangedEventHandler(UtilityExplorerContext_CurrentContextChanged);

        ns = (NavigationService)objExplorerService.Container.Components[1];
        //objExploreS = (ObjectExplorerService)objExplorerService.Container.Components[2];
        //sqlStudioExplorer = new SqlStudioExplorer();


        //ObjectExplorerService objExplorerService = (ObjectExplorerService)ServiceCache.ServiceProvider.GetService(typeof(IObjectExplorerService));
        //INodeInformation node = objExplorerService.FindNode(cs.Context);
        //if (node.Parent.InvariantName.Equals("Databases"))
        //{
        //    if (_databaseMenu == null)
        //    {
        //        string value = typeof(IMenuHandler).ToString();

        //        _databaseMenu = (HierarchyObject)node.GetService(typeof(IMenuHandler));
        //        String wtf = _databaseMenu.ToString();
        //        RestoreMenuItem rst = new RestoreMenuItem();
        //        _databaseMenu.AddChild(string.Empty, rst);
        //    }

        //}
        //ContextService cs = (ContextService)objExplorerService.Container.Components[0];

        //cs.ObjectExplorerContext.CurrentContextChanged += new NodesChangedEventHandler(Provider_SelectionChanged); 

        // for some reason calling GetSelectedNodes forces to add ContextService to ObjectExplorerService.Container.Components
        //int count = objExplorerService.Container.Components.Count;
        //int nodeCount; INodeInformation[] nodes;
        //objExplorerService.GetSelectedNodes(out nodeCount, out nodes);
        //count = nodeCount; count = nodes.Length;
        //count = objExplorerService.Container.Components.Count;

        //ContextService contextService = (ContextService)objExplorerService.Container.Components[1];
        //INavigationContextProvider provider = contextService.ObjectExplorerContext;

        //provider.CurrentContextChanged += new NodesChangedEventHandler(Provider_SelectionChanged);


    }
    catch (Exception ex)
    {
        MessageBox.Show("OnConnection::ERROR " + ex.Message);
    }
    #endregion
}
  • This might point you in the right direction. I had a similar problem and this helped me work through it. http://sqlblog.com/blogs/jonathan_kehayias/archive/2009/08/22/sql-2008-r2-breaks-ssms-addins.aspx – PseudoToad Jan 10 '13 at 16:17

3 Answers3

1

I know this one from in the grave. Your issue is because in the array objExplorerService.Container.Components ContextService isn't always the first element in the array. On my workstation the code you have works but when I gave my ssms addins to others it did not work because NavigationServer was at element [0]. Of course in the below sample you need to remove my logging and stuff but this should get you going if you didn't give up a year ago.

objExplorerService = (ObjectExplorerService)ServiceCache.ServiceProvider.GetService(typeof(IObjectExplorerService));
                    //cs = (ContextService)objExplorerService.Container.Components[0];
                    //cs.ObjectExplorerContext.CurrentContextChanged += new NodesChangedEventHandler(ObjectExplorerContext_CurrentContextChanged);
                    // cs.UtilityExplorerContext.CurrentContextChanged += new NodesChangedEventHandler(UtilityExplorerContext_CurrentContextChanged);

                    int count = objExplorerService.Container.Components.Count;

                    int nodeCount; INodeInformation[] nodes;

                    objExplorerService.GetSelectedNodes(out nodeCount, out nodes);
                    count = nodeCount; count = nodes.Length;
                    count = objExplorerService.Container.Components.Count;
                    ContextService contextService;
                    try
                    {
                         contextService = (ContextService)objExplorerService.Container.Components[1];
                    }
                    catch (Exception ex)
                    {
                        using (StreamWriter w = File.AppendText("c:\\temp\\log.txt"))
                        {
                            Log(ex.Message, w);
                            Log("Failed Adding Event ", w);
                        }
                        contextService = (ContextService)objExplorerService.Container.Components[0];

                    }
                    INavigationContextProvider provider = contextService.ObjectExplorerContext;
                    provider.CurrentContextChanged += new NodesChangedEventHandler(ObjectExplorerContext_CurrentContextChanged);
JStead
  • 1,710
  • 11
  • 12
0

Try to put your code within ext_ConnectMode.ext_cm_UISetup instead.

if (connectMode == ext_ConnectMode.ext_cm_UISetup)
{
   // < Your code here > 
}
else if (connectMode == ext_ConnectMode.ext_cm_AfterStartup)
{
   ...
}
Sam2
  • 1
-1

Try it like this :

_contextService = (ContextService) ServiceCache.ServiceProvider.GetService(typeof (IContextService));
_contextService.ActionContext.CurrentContextChanged += ActionContextOnCurrentContextChanged;
bensiu
  • 24,660
  • 56
  • 77
  • 117