InstalledInstances doesn't work

本文关键字:work doesn InstalledInstances | 更新日期: 2023-09-27 18:06:10

我有一个数据库项目,我必须创建一个安装文件来运行另一台计算机。我尝试设置,但首先,我需要知道是否有任何SQL Server已经安装在那台计算机上。我搜索了一些关于它的代码,我发现:

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

but everytime instances = null。但是当我试着在电脑上看我自己时,我发现我是用手看的。这个代码有什么问题?

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();
          }
       }
    }
}

InstalledInstances doesn't work

您需要去掉初始的':

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

但是当从32位。net可执行文件在64位机器上运行时,它实际上并没有报告安装的实例。这是因为它们只在注册表的64位视图中。要从。net 4下的32位进程到达那里,您可以使用以下代码:

var localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var rk = localMachine.OpenSubKey("SOFTWARE''Microsoft''Microsoft SQL Server");
var instances = (String[])rk.GetValue("InstalledInstances");

我不确定这是否是唯一的问题,但我注意到您正在转义"而不是',因此您需要在字符串上添加@前缀并双"而不是'",如:

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

使用@格式的字符串更容易,或者您可以返回并将目标路径中的'实例替换为''


从MSDN看来,你必须测试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();
        }

您需要检查所取的键,因为您可能没有指向正确的键,要知道您拥有的实际键是什么,请执行以下操作:

string keyValue = registryKey.ToString();

如果你发现一个不同的键,你一直在使用的是:SOFTWARE''Microsoft''Microsoft SQL Server,那么你应该改变项目的构建,因为注册表可以为32或64,所以指定哪个CPU, 不是"任何CPU"