Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to detect the presence of SMO?

Tags:

sql-server

smo

I have some code that uses SMO to populate a list of available SQL Servers and databases. While we no longer support SQL Server 2000, it's possible that the code could get run on a machine that SQL Server 2000 and not have the SMO library installed. I would perfer to check for SMO first and degrade the functionality gracefully instead of blowing up in the user's face. What is best way to detect whether or not SMO is available on a machine?

Every example that I have seen through a quick Google scan was a variation of "look for C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\Microsoft.SqlServer.Smo.dll". The problem with that approach is that it only works with SQL Server 2005. If SQL Server 2008 is the only SQL Server installed then the path will be different.

like image 602
Chris Miller Avatar asked Sep 03 '08 19:09

Chris Miller


4 Answers

I had a look at the SharedManagementObjects.msi from the SQL2008 R2 feature pack and my Windows Registry (SQL2008 R2 Dev is installed on this machine) and I believe these are the reg keys one should use to detect SMO (All under HKLM):

SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion - this is apparently the main key, indicating that some version of SMO is installed.

SOFTWARE\Microsoft\Microsoft SQL Server 2008 Redist\SharedManagementObjects\1033\CurrentVersion - this one probably means 2008 English is installed. Probably just checking for the presence of SOFTWARE\Microsoft\Microsoft SQL Server 2008 Redist\SharedManagementObjects would suffice.

Same applies to SQL2012: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server 2012 Redist\SharedManagementObjects\1033\CurrentVersion

But NOT SQL2005! even though I do have 2005 installed on this machine as well.

One more thing, You'd normally want Microsoft SQL Server System CLR Types as well, since SMO depends on them. The SQLSysClrTypes.msi has only one registry key: SOFTWARE\Microsoft\Microsoft SQL Server\RefCount\SQLSysClrTypes

like image 125
Zar Shardan Avatar answered Oct 04 '22 23:10

Zar Shardan


This is kind of clunky, but a quick check of the registry seems to work. Under HKEY_CLASSES_ROOT, a large number of classes from the SMO assemblies will be registered. All I needed to do was to pick one of the SMO classes and check for the existence of the key with the same name. The following function will return true if SMO has been installed, false if otherwise.

private bool CheckForSmo()
{
    string RegKeyName = @"Microsoft.SqlServer.Management.Smo.Database";
    bool result = false;
    Microsoft.Win32.RegistryKey hkcr = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(RegKeyName);
    result = hkcr != null;

    if (hkcr != null)
    {
        hkcr.Close();
    }

    return result;
}
like image 28
Chris Miller Avatar answered Oct 04 '22 23:10

Chris Miller


What I do is just try to create an instance of some SMO object. If it fails, its not there.

like image 27
Mostlyharmless Avatar answered Oct 05 '22 01:10

Mostlyharmless


Solution for SQL Server 2012:

HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion\Version

You can check if this key exists (and check if the value is greater than 11).

like image 43
Manni Avatar answered Oct 04 '22 23:10

Manni