4

I have a project with a database and I have to create a setup file to run another computer. I try to setup but firstly, I need to know is there any SQL Server already installed on that computer. I searched some code about it and I found:

RegistryKey rk = Registry.LocalMachine.OpenSubKey("\\SOFTWARE\\Microsoft\\Microsoft SQL Server");
String[] instances = (String[])rk.GetValue("InstalledInstances");

but everytime instances equal null everytime. But when I try to look myself on computer I find by hand. What's the wrong this code?

RegistryKey rk = Registry.LocalMachine.OpenSubKey("\\SOFTWARE\\Microsoft\\Microsoft SQL Server");
String[] instances = (String[])rk.GetValue("InstalledInstances");

if (instances.Length > 0)
{
   foreach (String element in instances)
   {
       if (element == "MSSQLSERVER")
       {
          DialogResult res = MessageBox.Show("are u sure to setup this file?", "UYARI", MessageBoxButtons.YesNo);
          if (res == DialogResult.Yes)
          {
             string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\SQLEXPR.EXE";
             Process p = new Process();
             p.StartInfo.FileName = path;
             p.StartInfo.Arguments = "/qb INSTANCENAME=\"SQLEXPRESS\" INSTALLSQLDIR=\"C:\\Program Files\\Microsoft SQL Server\" INSTALLSQLSHAREDDIR=\"C:\\Program Files\\Microsoft SQL Server\" INSTALLSQLDATADIR=\"C:\\Program Files\\Microsoft SQL Server\" ADDLOCAL=\"All\" SQLAUTOSTART=1 SQLBROWSERAUTOSTART=0 SQLBROWSERACCOUNT=\"NT AUTHORITY\\SYSTEM\" SQLACCOUNT=\"NT AUTHORITY\\SYSTEM\" SECURITYMODE=SQL SAPWD=\"\" SQLCOLLATION=\"SQL_Latin1_General_Cp1_CS_AS\" DISABLENETWORKPROTOCOLS=0 ERRORREPORTING=1 ENABLERANU=0";

             p.StartInfo.CreateNoWindow = true;
             p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
             p.Start();

             p.WaitForExit();
             CreateDB();
          }
          else
          {
             this.Close();
          }
       }
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Hakan Özler
  • 968
  • 1
  • 10
  • 22

3 Answers3

2

You need to drop the initial \:

Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Microsoft SQL Server");

But when run on my 64-bit machine from 32-bit .Net executable, it doesn't actually report the installed instances. That's because they are only in the 64-bit view of registry. To get there from 32-bit process under .Net 4, you can use this code:

var localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var rk = localMachine.OpenSubKey("SOFTWARE\\Microsoft\\Microsoft SQL Server");
var instances = (String[])rk.GetValue("InstalledInstances");
Community
  • 1
  • 1
svick
  • 236,525
  • 50
  • 385
  • 514
  • String[] instances = (String[])rk.GetValue("InstalledInstances"); this part everytime null . instances resuls null buy i have InstalledInstances – Hakan Özler Aug 21 '11 at 17:53
  • in my visual basic 2010 i "OpenBaseKey " can't used:S RegistryKey has just 3 method :S – Hakan Özler Aug 21 '11 at 18:02
  • Are you targeting .Net 4.0? Project properties → Compile → Advanced Compile Options → Target Framework. – svick Aug 21 '11 at 18:15
1

I'm not sure if this is the only problem but I notice you are escaping the " and not the \ so you want an @ prefix on the string and double " instead of \" like so:

  p.StartInfo.Arguments = @"/qb INSTANCENAME=""SQ... rest of string ... ";

Using the @ formatted strings is easier IMHO or you could go back and replace every instance of \ in the target path with \\


From MSDN it seems you have to test for 32 vs 64

      try
        {
            // That works fine in Win32 but not in Win64
            return Registry.LocalMachine.OpenSubKey("Software\\XXX\\YYY").GetValue("Path").ToString();
        }
        catch (Exception)
        {
            // That works fine in Win64 but not in Win32
            return Registry.LocalMachine.OpenSubKey("\\Software\\XXX\\YYY").GetValue("Path").ToString();
        }
Hogan
  • 69,564
  • 10
  • 76
  • 117
  • my mistake is top , in my computer have a mssqlserver but in the code resuls null RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\"); String[] instances = (String[])rk.GetValue("InstalledInstances"); – Hakan Özler Aug 21 '11 at 17:27
0

you need to check what key is taken, because you might not pointing to the correct key, to know what actual key that you have do this:

string keyValue = registryKey.ToString();

if you found a different key that what you have been using which is: SOFTWARE\\Microsoft\\Microsoft SQL Server, then you should change the projects build, since the registries can be for 32 or 64, so specify which CPU, not "any CPU"

ibr
  • 319
  • 1
  • 5
  • 19