以编程方式查找SQL Server的所有实例
我知道有很多与此主题相似的主题,但是没有一个主题提供了我想要的正确答案.
I know that there's quite a few subjects similar to this one, but none of them provided the correct answer I am looking for.
我正在努力收集我们网络上所有SQL-Server实例.它应该能够检测到正在运行哪个版本的SQl-Server.我们运行的不同版本在" SQL Server 2000
"和" SQL Server 2008 R2
"
I am struggling to gather all the instances of SQL-Server on our network. It should be able to detect what version of SQl-Server is running. The different versions we have running vary between 'SQL Server 2000
' and 'SQL Server 2008 R2
'
为了给您提供一些背景信息,目前我正在我们的局域网上进行开发,但是稍后将在我们的服务器上运行以收集信息.
To give you a little background information, currently I am developing on our local network, but later on it will be run on our servers to gather information.
收集到的一些信息是:
- 应用程序池
- iis安装
- 服务器上的所有数据库
- 还有更多类似的东西
以上所有内容都可以通过WMI查询正常运行.但是我无法通过WMI或Visual Studio 2010中的名称空间获得SQl-Server的正确实例.
This all above is working without a problem through WMI queries. But I can not get the correct instances of SQl-Server by WMI or namespaces within Visual Studio 2010.
我根据在stackoverflow和其他站点周围发现的其他解决方案尝试过的一些事情:
Some of the things I've tried according to other solutions found around stackoverflow and other sites:
- WMI,使用不同的名称空间,例如
root \\ Microsoft \\ SqlServer \\ ComputerManagement10
和ServerSettings
类.但这仅提供了没有版本号的SQLSERVER和SQLEXPRESS.使其变得毫无用处. - 我还尝试了
root \\ CIMV2 Win32_Product
,其中包括sql子句.但这返回的数据远远超过我想要的.另外,查询本身非常慢. - 稍后,我在Visual Studio中找到了一些类,例如
SqlDataSourceEnumerator
.尽管这仅在某些服务正在运行并且某些端口处于打开状态时才有效.由于可能的安全问题和可能的不正确数据,我们最好不这样做 - 我还看到有些人指的是其他一些名称空间(一旦我再次找到它们,就会在这里写它们),但是msdn表示我们将在不久的将来删除这些名称空间.
- WMI, using varying namespaces such as
root\\Microsoft\\SqlServer\\ComputerManagement10
with theServerSettings
class. But this only gives SQLSERVER and SQLEXPRESS without a version number. Making it kind of useless. - I also tried
root\\CIMV2 Win32_Product
including a where like sql clause. But this returns much more data than just what I am looking for. In addition the query itself is very slow. - Later on I found some Classes within Visual Studio such as
SqlDataSourceEnumerator
for example. Though this only works if a certain service is running and some ports are open. Which we preferably not do due to possible security issues and possible incorrect data - I also saw some people referring to some other namespaces (will write them here once I find them again), but msdn stated that these namespaces we're going to be removed in the near future.
总结:我需要检索域中版本在2000到2008 R2之间的所有 SQL-Server
实例.
To summarize: I need to retrieve all installed instances of SQL-Server
on a domain with versions varying between 2000 and 2008 R2.
好,所以我解决了这个问题.我所做的是几件事:
Ok so I resolved the issue. What I have done is a few things:
- 首先,我在域中扫描计算机.
- 检查SQLBrowser服务是否正在运行,如果没有运行,请启动它!这是由位于
system.ServiceProcess
中的 - 启动所有SQLBrowser之后,我使用
SqlDataSourceEnumerator
枚举所有实例.
ServiceController类
完成的- First I scan the domain for machines.
- Check if the SQLBrowser service is running, if not, start it! which is done by the
ServiceController class
located insystem.ServiceProcess
- After all the SQLBrowser have been started I use the
SqlDataSourceEnumerator
to enumerate through all the instances.
对于那些对代码感兴趣的人:
注意:您需要网络管理员权限才能在远程计算机上启动它.
For those interested in the code:
Note: you need network admin rights to start it on the remote machines.
public void StartSqlBrowserService(List<String> activeMachines)
{
ServiceController myService = new ServiceController();
myService.ServiceName = "SQLBrowser";
foreach (var machine in activeMachines)
{
try
{
myService.MachineName = machine;
string svcStatus = myService.Status.ToString();
switch (svcStatus)
{
case "ContinuePending":
Console.WriteLine("Service is attempting to continue.");
break;
case "Paused":
Console.WriteLine("Service is paused.");
Console.WriteLine("Attempting to continue the service.");
myService.Continue();
break;
case "PausePending":
Console.WriteLine("Service is pausing.");
Thread.Sleep(5000);
try
{
Console.WriteLine("Attempting to continue the service.");
myService.Start();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
break;
case "Running":
Console.WriteLine("Service is already running.");
break;
case "StartPending":
Console.WriteLine("Service is starting.");
break;
case "Stopped":
Console.WriteLine("Service is stopped.");
Console.WriteLine("Attempting to start service.");
myService.Start();
break;
case "StopPending":
Console.WriteLine("Service is stopping.");
Thread.Sleep(5000);
try
{
Console.WriteLine("Attempting to restart service.");
myService.Start();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
break;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
然后这就是我用来检索实例的东西.
And then this is what I use to retrieve the instances.
public static void SqlTestInfo()
{
SqlDataSourceEnumerator instance = SqlDataSourceEnumerator.Instance;
DataTable table = instance.GetDataSources();
DisplayData(table);
}
private static void DisplayData(DataTable table)
{
foreach (DataRow row in table.Rows)
{
foreach (DataColumn dataColumn in table.Columns)
{
Console.WriteLine("{0} = {1}", dataColumn.ColumnName, row[dataColumn]);
}
Console.WriteLine();
}
}
这可能不是最佳解决方案,有些人可能觉得它有些脏.但是目前,这是我能得到的最好的解决方法.
希望这可以帮助将来有同样问题的任何人.
It may not be the best solution, some may find it somewhat dirty. But for now it's the best workaround I could get.
Hope this helps any people in the future having the same problem.