private static void TryKey(RegistryKey k1, LocalInstanceInfo ret, string instanceName)
        {
            string rawVersion = null;

            using (RegistryKey rk = k1.OpenSubKey(@"MSSQLServer\CurrentVersion", false))
                if (rk != null)
                {
                    rawVersion = rk.GetValue("CurrentVersion") as string;
                }

/*
 *          string rawPath = null;
 *          using (RegistryKey rk = k1.OpenSubKey(@"Setup", false))
 *              if (rk != null)
 *                  rawPath = rk.GetValue("SQLPath") as string;
 */


            if (!string.IsNullOrEmpty(rawVersion) /* && rawPath != null && Directory.Exists(rawPath) */)
            {
                try
                {
                    Version ver = new Version(rawVersion);
                    var     i   = new LocalInstanceInfo.SqlInstance(instanceName);
                    i.FileVer = ver;
                    ret.Instances.Add(i);
                }
                catch
                {
                }
            }
        }
        private static void GetList(LocalInstanceInfo ret)
        {
            using (RegistryKey lm = Registry.LocalMachine)
            {
                // default instance
                using (RegistryKey k0 = lm.OpenSubKey(@"SOFTWARE\Microsoft\MSSQLServer"))
                    if (k0 != null)
                    {
                        TryKey(k0, ret, string.Empty);
                    }

                // named instances
                using (RegistryKey k1 = lm.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server", false))
                    if (k1 != null)
                    {
                        foreach (string subKeyName in new List <string>(k1.GetSubKeyNames() ?? new string[0]))
                        {
                            using (RegistryKey candidate = k1.OpenSubKey(subKeyName))
                                if (candidate != null)
                                {
                                    TryKey(candidate, ret, subKeyName);
                                }
                        }
                    }
            }
        }
        public static LocalInstanceInfo Get()
        {
            LocalInstanceInfo ret = new LocalInstanceInfo();

            GetList(ret);
            var filtered = new List <LocalInstanceInfo.SqlInstance>();

            foreach (LocalInstanceInfo.SqlInstance i in ret.Instances)
            {
                string  path;
                Version version;
                ServiceControllerStatus status;
                if (TryService(LocalInstanceInfo.GetServiceKey(i.Name), out path, out version, out status))
                {
                    i.Status = status;
                    filtered.Add(i);
                }
            }

            ret.Instances.Clear();
            ret.Instances.AddRange(filtered);

            ret.SortByVersionDescending();
            return(ret);
        }
/*
 *      static LocalInstancesDiscovery()
 *      {
 *          try
 *          {
 *              LocalInstanceInfo i = new LocalInstanceInfo();
 *              StringBuilder dump = new StringBuilder();
 *              var stringWriter = new StringWriter(dump);
 *              i.WriteToXml(stringWriter);
 *              Trace.WriteLine("");
 *          }
 *          catch (Exception)
 *          {
 *          }
 *      }
 */

        public static LocalInstanceInfo GetFull(TimeSpan timeout)
        {
            LocalInstanceInfo ret = new LocalInstanceInfo();

            GetList(ret);
            BuildDescription(ret, timeout);
            ret.SortByVersionDescending();
            return(ret);
        }
        static void BuildDescription(LocalInstanceInfo info, TimeSpan timeout)
        {
            if (info.Instances.Count > 0)
            {
                List <ManualResetEvent> events = new List <ManualResetEvent>();
                foreach (LocalInstanceInfo.SqlInstance instance in info.Instances)
                {
                    // description
                    LocalInstanceInfo.SqlInstance sqlInstance = instance;
                    ManualResetEvent ev = new ManualResetEvent(false);
                    events.Add(ev);
                    ThreadPool.QueueUserWorkItem(
                        delegate
                    {
                        try
                        {
                            // Console.WriteLine(i2.FullLocalName + ": " + Thread.CurrentThread.ManagedThreadId);
                            // Thread.Sleep(3000);
                            string fullPath;
                            Version productVersion;
                            ServiceControllerStatus status;
                            if (TryService(LocalInstanceInfo.GetServiceKey(sqlInstance.Name), out fullPath, out productVersion, out status))
                            {
                                sqlInstance.Status = status;
                                sqlInstance.Ver    = productVersion;

                                if (sqlInstance.Status == ServiceControllerStatus.Running)
                                {
                                    string cs = "Data Source=" + sqlInstance.FullLocalName + ";Integrated Security=SSPI;Pooling=False;";
                                    using (SqlConnection con = new SqlConnection(cs))
                                        using (SqlCommand cmd = new SqlCommand("Select @@version, SERVERPROPERTY('ProductLevel'), SERVERPROPERTY('Edition')", con))
                                        {
                                            cmd.CommandTimeout = (int)timeout.TotalSeconds;
                                            con.Open();
                                            using (SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SingleRow))
                                            {
                                                if (rdr.Read())
                                                {
                                                    string description = (string)rdr.GetString(0);
                                                    string level       = (string)rdr.GetString(1);
                                                    string edition     = (string)rdr.GetString(2);

                                                    description =
                                                        description.Replace("\t", " ").Replace("\r", " ").Replace("\n", " ");

                                                    while (description.IndexOf("  ") >= 0)
                                                    {
                                                        description = description.Replace("  ", " ");
                                                    }

                                                    sqlInstance.IsOK        = true;
                                                    sqlInstance.Description = description;
                                                    sqlInstance.Level       = level;
                                                    bool isExpress          =
                                                        edition.IndexOf("Desktop Engine") >= 0 ||
                                                        edition.IndexOf("Express Edition") >= 0;

                                                    sqlInstance.Edition = isExpress ? SqlEdition.Express : SqlEdition.LeastStandard;
                                                }
                                            }
                                        }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(
                                "Failed to connect to " + sqlInstance.FullLocalName + ". See Details Below" + Environment.NewLine +
                                ex + Environment.NewLine);
                        }
                        finally
                        {
                            ev.Set();
                        }
                    });
                } // done: description


                WaitHandle.WaitAll(events.ToArray());

                List <LocalInstanceInfo.SqlInstance> normal = info.Instances.FindAll(delegate(LocalInstanceInfo.SqlInstance i) { return(i.Ver != null); });
                info.Instances.Clear();
                info.Instances.AddRange(normal);
            }
        }