How can I detect if SQL is installed on the local machine using C#? Is it possible to check a remote machine?
-
added the sql-server tag since this question does relate to SQL Server as well – StevenMcD Aug 03 '09 at 09:59
-
2A specific version? Any version? Does bitness matter (32-bit or 64-bit)? Editions? Does it matter if its actually running? Does it matter if you are able to access it? What exactly do you need to find out? "Installed or not" is not as clear cut as it may seem. – Sander Aug 03 '09 at 10:00
-
2If you don't take the time to formulate a good question, don't expect others to take the time to answer it. – bug-a-lot Aug 03 '09 at 10:03
-
@bug-a-lot: strange but on SO there are so many people eager to get some points so even unclear or duplicate answers will be answered if the answer is simple :) people try to guess what author meant. Is this bad? I think no. As developers we are often forced to "guess" because specifications are always unclear and deadline is always close, so we cannot afford waiting 2 weeks while anybody on customer's side will have a desire to clarify. :) – Bogdan_Ch Aug 03 '09 at 14:03
8 Answers
You've got several ways to do it:
- SmoApplication.EnumAvailableSqlServers()
- SqlDataSourceEnumerator.Instance
- Direct access to system registry
Direct access isn't the recommended solution by MS, because they can change keys/paths. But the other solutions fails providing instances on 64-bit platforms.
Therefore I prefer to check SQL Server instances in System Registry. Doing that, keep in mind the difference in Registry access between x86 and x64 platforms. Windows 64-bit stores data in different parts of system registry and combines them into views. So using RegistryView (available since .NET 4) is essential.
using Microsoft.Win32;
RegistryView registryView = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
using (RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
{
RegistryKey instanceKey = hklm.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL", false);
if (instanceKey != null)
{
foreach (var instanceName in instanceKey.GetValueNames())
{
Console.WriteLine(Environment.MachineName + @"\" + instanceName);
}
}
}
If you are looking for 32-bit instances on a 64-bit OS (pretty weird, but possible), you will need to look:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server

- 8,168
- 8
- 71
- 87
-
1Would be worth to note that RegistryView is only available in .NET 4 and later. – Gayan Dasanayake Apr 17 '13 at 03:40
-
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.
We check the registry for that
Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\CurrentVersion", ", "0.0.0.0");

- 4,252
- 5
- 47
- 70

- 64,563
- 18
- 145
- 216
-
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 Aug 03 '09 at 10:12
You could use the System.Management namespace to check for the existence of SQL Server in the server's running services.

- 17,262
- 11
- 42
- 54
You will need SQL 2005 Backwards Compatibility redist. See: How to Connect to Sqlserver2008 using SMO any workaround has to be done?
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.
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

- 787
- 7
- 14
-
+1 This helped in checking remote machines. I needed to know if a non-running sql server was installed, too. So I used Preet Sangha's solution in that case. – TamusJRoyce Feb 21 '11 at 01:25
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.

- 2,085
- 2
- 20
- 28
Thanks a lot to Dejan Stanič.
And I wanted to add more search criteria:
Check if SQL Server 2008 is installed on local machine in .net sqlclient

- 191,379
- 34
- 261
- 317

- 2,159
- 1
- 15
- 9