How To : Create SQL Server Management Studio Addin

28/07/2008

10 comments

image

Read the full and original article from Jon Sayce Here

In the last post I talked about How To: Create Windows Live Messenger Addin

Now let’s create SQL Server Management Studio Addin.

Start:

Let’s open Visual Studio and create a new Visual Studio Add-in project.

Step1

Check the right options for your Addin.

step3

After you finish the wizard please add new Setup project.

step4

Add Project output  -> Primary output and change the output group registration to vsdrpCOM

step5

Enter to Registry Editor and add your Addin to SSMS startup.

step6 

 

References

There’s extensive documentation on MSDN regarding Visual Studio’s EnvDTE object model, which is at the heart of Visual Studio add-in development, and most of this applies to SSMS. Most UI elements are the same for both environments but if your add-in relates to anything SQL-specific then you’re going to need references to SSMS assemblies and the documentation on these is non-existent.

IDTExtensibility2 Events

Once you’ve got the references sorted out, you’re ready to start coding.

The template class that Visual Studio has created implements the IDTExtensibility2 interface, but only one of the methods has any code in it so far: OnConnection.

OnConnection “occurs whenever an add-in is loaded into Visual Studio” according to MSDN – in our case the event will fire whenever you start SSMS, once the add-in is installed.

OnConnection will probably be the most important method of the interface for your add-in, but the others can be useful if you need to save settings as the add-in is unloaded or something similar.

SSMS Events

Handling SSMS events is one of the trickier aspects of writing the add-in, the problem being that you don’t know what events there are to handle. I suspect Reflector could help here, but the method I used was suggested by Sean.

To add a handler to an event we need to know the command to which that event belongs. The easiest way to find this is to loop through the commands and look for the name which sounds most like what you’re after.

For Each com As Command In _DTE.Commands
   Debug.WriteLine(String.Format("Name={0} | GUID={1} | ID={2}", com.Name, com.Guid, com.ID))
Next

Now we complete our Addin infrastructure we can start writing some code!!!

Edit Connect.vb and add a MessageBox inside OnStartupComplete method.

image

Build the project and install the Addin, open SSMS and this is what you should see.

step7

Add New Menu Item

Under Connect Class change to :
Implements the constructor for the Add-in object

Implements IDTExtensibility2
Implements IDTCommandTarget
 
Private _DTE2 As DTE2
Private _DTE As DTE
Private _addInInstance As AddIn
 
Private _CommandEvents As CommandEvents
 
Private _CommandBarControl As CommandBarControl
 
Private Const COMMAND_NAME As String = "MySSMSAddinCommand"

OnConnection Method:
get the events for the command we’re interested in (the GUID comes from the output of the previous debug command)
 NOTE: if the _CommandEvents object goes out of scope then the handler will not longer be attached to the event, so it must be a private class-level declaration rather than a local one.

Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection
       _DTE2 = CType(application, DTE2)
       _DTE = CType(application, DTE)
       _addInInstance = CType(addInInst, AddIn)
 
       _CommandEvents = _DTE.Events.CommandEvents("{84125960-B63C-3794-B5D3-9BC47A513E8D}", 1)
   End Sub

OnDisconnection Method: -
Checks whether the control in the tools menu is there if so delete the menu item.

Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) Implements IDTExtensibility2.OnDisconnection
        Try
            If Not (_CommandBarControl Is Nothing) Then
                _CommandBarControl.Delete()
            End If
        Catch
        End Try
    End Sub

QueryStatus Method:
called when the command’s availability is updated

Public Sub QueryStatus(ByVal commandName As String, ByVal neededText As vsCommandStatusTextWanted, ByRef status As vsCommandStatus, ByRef commandText As Object) Implements IDTCommandTarget.QueryStatus
       If neededText = vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then
           If commandName = _addInInstance.ProgID & "." & COMMAND_NAME Then
               status = CType(vsCommandStatus.vsCommandStatusEnabled + vsCommandStatus.vsCommandStatusSupported, vsCommandStatus)
           Else
               status = vsCommandStatus.vsCommandStatusUnsupported
           End If
       End If
   End Sub

OnStartupComplete Method:

Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete
        Dim myCommand As Command = Nothing
 
        ' -----------------------------------
        ' 1. Check whether the command exists
        ' -----------------------------------
 
        ' try to retrieve the command, in case it was already created
        Try
            myCommand = _DTE.Commands.Item(_addInInstance.ProgID & "." & COMMAND_NAME)
        Catch
            ' this just means the command wasn't found
        End Try
 
        ' ----------------------------------
        ' 2. Create the command if necessary
        ' ----------------------------------
 
        If myCommand Is Nothing Then
            myCommand = _DTE.Commands.AddNamedCommand(_addInInstance, COMMAND_NAME, "MySSMSAddin MenuItem", "Tooltip for your command", True, 0, Nothing, vsCommandStatus.vsCommandStatusSupported Or vsCommandStatus.vsCommandStatusEnabled)
        End If
 
        ' ------------------------------------------------------------------------------------
        ' 3. Get the name of the tools menu (may not be called "Tools" if we're not in English
        ' ------------------------------------------------------------------------------------
 
        Dim toolsMenuName As String
        Try
 
            ' If you would like to move the command to a different menu, change the word "Tools" to the 
            ' English version of the menu. This code will take the culture, append on the name of the menu
            ' then add the command to that menu. You can find a list of all the top-level menus in the file
            ' CommandBar.resx.
            Dim resourceManager As System.Resources.ResourceManager = New System.Resources.ResourceManager("MySSMSAddin.CommandBar", System.Reflection.Assembly.GetExecutingAssembly())
 
            Dim cultureInfo As System.Globalization.CultureInfo = New System.Globalization.CultureInfo(_DTE2.LocaleID)
            toolsMenuName = resourceManager.GetString(String.Concat(cultureInfo.TwoLetterISOLanguageName, "Tools"))
 
        Catch e As Exception
            'We tried to find a localized version of the word Tools, but one was not found.
            '  Default to the en-US word, which may work for the current culture.
            toolsMenuName = "Tools"
        End Try
 
        ' ---------------------
        ' 4. Get the Tools menu
        ' ---------------------
 
        Dim commandBars As CommandBars = DirectCast(_DTE.CommandBars, CommandBars)
        Dim toolsCommandBar As CommandBar = commandBars.Item(toolsMenuName)
 
        ' -------------------------------------------------
        ' 5. Create the command bar control for the command
        ' -------------------------------------------------
 
        Try
            'Find the appropriate command bar on the MenuBar command bar:
            _CommandBarControl = DirectCast(myCommand.AddControl(toolsCommandBar, toolsCommandBar.Controls.Count + 1), CommandBarControl)
            _CommandBarControl.Caption = "MySSMSAddin"
        Catch argumentException As 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.
        End Try
    End Sub

 

Build and Install

step8

Add New Window

Let’s make our menu item a functioning menu item.
First add new UserControl to the project

image

Modify the UserControl to your needs.

Add this code into Exec Method in Connect.vb
Define a new window as container for the UserControl.

Public Sub Exec(ByVal commandName As String, ByVal executeOption As vsCommandExecOption, ByRef varIn As Object, ByRef varOut As Object, ByRef handled As Boolean) Implements IDTCommandTarget.Exec
    handled = False
    If executeOption = vsCommandExecOption.vsCommandExecOptionDoDefault Then
        If commandName = _addInInstance.ProgID & "." & COMMAND_NAME Then
 
            ' get windows2 interface
            Dim MyWindow As Windows2 = CType(_DTE2.Windows, Windows2)
 
            ' get current assembly
            Dim asm As Assembly = System.Reflection.Assembly.GetExecutingAssembly
 
            ' create the window
            Dim MyControl As Object = Nothing
            Dim toolWindow As Window = MyWindow.CreateToolWindow2(_addInInstance, asm.Location, "MySSMSAddin.MyAddinWindow", "MySMSAddin Window", "{5B7F8C1C-65B9-2aca-1Ac3-12AcBbAF21d5}", MyControl)
            toolWindow.Visible = True
 
            handled = True
 
        End If
    End If
End Sub

 

image

image 

Download MySSMSAddin Project

Add comment
facebook linkedin twitter email

Leave a Reply

10 comments

  1. Amwarul01/12/2008 ב 09:00

    Thanks Raiten.
    This great article.
    Here I’m looking SQL Server 2000 Addin. is this possile? Please guide me.

    Thanks in Advance

  2. Hugh Gleaves26/03/2009 ב 14:56

    I was unsure whether this article referred to SQL Server 2008 or not. Also the step where you edit the registry for the setup was confusing. Are we expected to add the nodes ‘Microsoft’ and everything below? In my system the Visual Studio 2008 IDE, when editing the setup registry, show nothing beneath ‘Software’.

    I therefore stopped at this stage, because I was unsure of the exact registry nodes to refer to for my system which is Vista running SQL Server 2008.

    Overall a fascinating article though.

  3. Sam24/05/2009 ב 07:25

    Thanks for the article.

    I wonder if anyone was able to answer Hugh Gleaves question. I am having the same problem and I almost have the same setup except I am running everything under Windows XP.

    Thanks,

  4. mfelch11/08/2009 ב 19:04

    You have to manually rename the Microsoft node and add new keys as needed.

  5. Craig09/11/2009 ב 23:11

    I find this article useless without information about how to debug an SSMS add in.

    If I open your project in visual studio 2008 and hit F5 it compiles but tries to launch visual studio 2008 and not SSMS 2008. If I change it to use the SSMS exe then i get the wonderful error that /resetaddin doesnt work with SSMS.

    Can you explain what is required to debug this project?

  6. roulette strategie15/01/2010 ב 16:03

    Lustig, ich hätte garnicht gedacht das das *wirklich* so funktioniert. Komische Welt.

  7. bookofraonlinespielen.biz04/04/2011 ב 04:00

    Lustig, ich hätte never ever gedacht, dass dies wirklich so funktionieren kann ;)