views:

1187

answers:

6

How can I detect if SQL is installed on the local machine using C#? Is it possible to check a remote machine?

+1  A: 

You could use the System.Management namespace to check for the existence of SQL Server in the server's running services.

FailBoy
+1  A: 

You can check registry path

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\InstalledInstances

For an example of code that does similar work, see this quesion how-to-get-sql-server-installation-path-programatically

Please also see MSDN: File Locations for Default and Named Instances of SQL Server for more details on registry keys used by SQL Server.

Bogdan_Ch
ouch just before me :-)
Preet Sangha
+1  A: 

We check the the registry

Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\CurrentVersion", ", "0.0.0.0");
Preet Sangha
Some key values for MS SQL server could be found in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server key, and some in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\ so both my and Preet's solutions have chances to be implemented. But, NOTE: things in registry can be different on WinXP\Vista and Win Server 2003/2008 so you need to check your code carefully on all Windows versions where it is supposed to run
Bogdan_Ch
And also if you install 64 or 32 bit on 64 or 32 machine....
Preet Sangha
A: 

You will need SQL 2005 Backwards Compatibility redist. See: http://stackoverflow.com/questions/1135636/how-to-connect-to-sqlserver2008-using-smo-any-workaround-has-to-be-done/1135683#1135683

using Microsoft.SqlServer.Management.Smo;

DataTable dt = SmoApplication.EnumAvailableSqlServers(true);
         string[] szSQLInstanceNames = new string[dt.Rows.Count];
         StringBuilder szSQLData = new StringBuilder();

         if (dt.Rows.Count > 0)
         {
            int i = 0;
            foreach (DataRow dr in dt.Rows)
            {
               try
               {
                  szSQLInstanceNames[i] = dr["Name"].ToString();
                  Server oServer;
                  oServer = new Server(szSQLInstanceNames[i]);
                  if (string.IsNullOrEmpty(dr["Instance"].ToString()))
                  {
                     szSQLInstanceNames[i] = szSQLInstanceNames[i] + "\\MSSQLSERVER";
                  }
                  szSQLData.AppendLine(szSQLInstanceNames[i] + "  Version: " + oServer.Information.Version.Major + "  Service Pack: " + oServer.Information.ProductLevel + "  Edition: " + oServer.Information.Edition + "  Collation: " + oServer.Information.Collation);
               }
               catch (Exception Ex)
               {
                  szSQLData.AppendLine("Exception occured while connecting to " + szSQLInstanceNames[i] + " " + Ex.Message);
               }

               i++;
            }

Note: if you just want to see if Default intance is installed or no just do:

Server oServer; oServer = new Server(Environment.MAchineName);

if it does not throw an exception, the SQL exists.

Ganesh R.
A: 

You could just open a connection to the machine and close it. If you throw an exception that's a decent sign. I realize it's not super clean but it'll get the job done.

Jon
A: 

Perhaps you'll find the following useful. Use first method to find about servers (local & network), then you can use the second to enumerate databases on each server.

using System;
using System.Collections.Generic;
using System.Data.Sql;
using System.Data;
using System.Data.SqlClient;

namespace Info.Data.Engine.SQLServer
{
  public static class SQLServerHelper
  {
    public static List<String> EnumerateServers()
    {
      var instances = SqlDataSourceEnumerator.Instance.GetDataSources();
      if ((instances == null) || (instances.Rows.Count < 1)) return null;

      var result = new List<String>();
      foreach (DataRow instance in instances.Rows)
      {
        var serverName = instance["ServerName"].ToString();
        var instanceName = instance["InstanceName"].ToString();
        result.Add(String.IsNullOrEmpty(instanceName) ? serverName : String.Format(@"{0}\{1}", serverName, instanceName));
      }
      return result;
    }

    public static List<String> EnumerateDatabases(String connectionString)
    {
      try
      {
        using (var connection = new SqlConnection(connectionString))
        {
          connection.Open();
          var databases = connection.GetSchema("Databases");
          connection.Close();
          if ((databases == null) || (databases.Rows.Count < 1)) return null;

          var result = new List<String>();
          foreach (DataRow database in databases.Rows)
          {
            result.Add(database["database_name"].ToString());
          }
          return result;
        }
      }
      catch
      {
        return null;
      }
    }
  }
}

HTH, Dejan

Dejan Stanič