InstalledInstances不起作用

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

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

但每次实例每次都等于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(); } } } } 

你需要删除最初的\

 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对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“