Click here to Skip to main content
Click here to Skip to main content

Alter SQLServer 2005 Most Recent List

, 15 Mar 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
Demonstrates how to Adjust the SQL2005 MRU using Reflection and the SQL Assemblies

Introduction

I have a number of Servers in my Microsoft SQL Server Management Studio Server list that are no longer accessible, and not wanting to completely rebuild my list I began by posting a question on ServerFault about being able to Edit the MRU list for SQL Server Management Studio and being told it was not possible, I investigated whether infact it really would be. So I dug out Reflector and had a look inside the SQL Management Studio DLLs to find out, turns out... you can.

Using the Code

Because this code requires some libraries that are included with Microsoft SQL Server Management Studio, I cannot redistribute them. But if you open the project and add a reference to them, you'll then be able to compile.

References that need to be added can be either from SSMS Express or Full for version 2005. (I have noted the locations in CheckAssembly.vb.)

'Express - 'C:\Program Files\Microsoft SQL Server\90\Tools\Binn\
VSShell\Common7\IDE\Microsoft.SqlServer.Express.ConnectionDlg.dll

'Full - C:\Program Files\Microsoft SQL Server\90\Tools\Binn\
VSShell\Common7\IDE\ConnectiondDlg.dll	 

Note that to find the information about what properties and objects are used inside the component, we need to use Reflector.

reflectoroutput.png

Once we actually know how to find the properties and methods of interest, we need to actually hookup to them so we can make use of them. It is important to note that because a number of the objects are declared privately inside the library, we can't use strong types so we just use GetType to ensure that things work as we expect.

For Each pp As PropertyInfo In _
  GetType(ConnectionDlg.Personalization).GetProperties_
	(BindingFlags.Static Or BindingFlags.NonPublic)
    If String.Equals(pp.Name, "Instance") Then
        t = CType(pp.GetValue(GetType(ConnectionDlg.Personalization), Nothing), _
         ConnectionDlg.Personalization)
        Exit For
    End If
Next

Now that we have found the reflected internal instance of the Object, we can start to operate on that to build up our Onscreen List of Servers that can be used. The EnumObject method is how I called the reflected method and then enabled the ability to also delete from the same list.

 Dim d As System.Collections.Specialized.HybridDictionary = Nothing

For Each ff As FieldInfo In t.GetType.GetFields_
	(BindingFlags.NonPublic Or BindingFlags.Instance)
    Debug.Print(ff.Name)

    Select Case ff.Name
        Case "typeTable"
            d = CType(ff.GetValue(t), System.Collections.Specialized.HybridDictionary)
    End Select
Next

If d IsNot Nothing Then
    sl = d.Item(g)
    EnumObject(sl, False)
End If

EnumObject is recursive because the list is a linked list and we need to be able to traverse the list to find the actual data, because the original object has a String method which just returns a copy of the data, but not the actual objects.

Private Sub EnumObject(ByVal o As Object, ByVal remove As Boolean)
    Dim head As Object
    Dim nextitem As Object

    If o Is Nothing Then Return

    'Debug.Print("Enum object - " & o.GetType.ToString & " (Fields)")
    For Each ff As FieldInfo In o.GetType.GetFields_
	(BindingFlags.NonPublic Or BindingFlags.Instance)
        If String.Equals(ff.Name, "head", StringComparison.OrdinalIgnoreCase) Then
            head = ff.GetValue(o)
            EnumObject(head, remove)
        End If

        If String.Equals(ff.Name, "next", StringComparison.OrdinalIgnoreCase) Then
            nextitem = ff.GetValue(o)

            EnumObject(nextitem, remove)
        End If

    Next   
    
    'more code here about actually getting the data
End Sub

Finally, once we have displayed the list of servers to the user, we allow them to select one in the Listbox and then click Remove. This will then call EnumObjects again, but enabling the Delete of the record.

Points of Interest

Because all of the methods and classes are Private inside the SQL libraries, the only real way to access them is using Reflection.

Beware this has only been tested with SQL2005 and is only really something I did to solve my particular issue.

If you choose to run this program, make sure your SQL Server Management Studio is closed before you run it, because I'm not sure exactly who writes the file and when.

History

  • 2010-03-11 First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Paul Farry
Architect
Australia Australia
I've worked on Networking applications, Point of Sale systems, Distributed Server Controllers, and multiple Plugin Architectures for various Services that I've built for the companies I've worked for over the years.
 
I'm currently working for a Software Development company building the Installation system for a large scale corporate packages with hundreds of disparate models that are deployed to Cloud server instances.

Comments and Discussions

 
GeneralSSMS 2008 Pinmemberdiegopandolfo2-Mar-11 2:37 
GeneralRe: SSMS 2008 PinmemberPaul Farry3-Mar-11 17:07 
GeneralRe: SSMS 2008 PinmemberAndrei Rantsevich21-Mar-12 13:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141022.2 | Last Updated 15 Mar 2010
Article Copyright 2010 by Paul Farry
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid