【问题标题】:Find all instances of sql server programmatically以编程方式查找所有 sql server 实例
【发布时间】:2012-11-13 15:08:54
【问题描述】:

我知道有很多类似的主题,但没有一个提供我正在寻找的正确答案。

我正在努力收集我们网络上的所有 SQL-Server 实例。它应该能够检测到正在运行的 SQl-Server 版本。我们运行的不同版本在“SQL Server 2000”和“SQL Server 2008 R2”之间变化

为了给你一些背景信息,目前我正在我们的本地网络上开发,但稍后它将在我们的服务器上运行以收集信息。

收集到的一些信息是:

  • 应用程序池
  • iis 安装
  • 服务器上的所有数据库
  • 还有一些类似的东西

以上所有内容都可以通过 WMI 查询正常工作。但我无法通过 WMI 或 Visual Studio 2010 中的命名空间获得正确的 SQl-Server 实例。

根据在 stackoverflow 和其他网站上找到的其他解决方案,我尝试了一些事情:

  1. WMI,使用不同的命名空间,例如 root\\Microsoft\\SqlServer\\ComputerManagement10ServerSettings 类。但是这只给出了没有版本号的 SQLSERVER 和 SQLEXPRESS。让它有点没用。
  2. 我还尝试了root\\CIMV2 Win32_Product,包括一个 where like sql 子句。但这会返回比我正在寻找的更多的数据。此外,查询本身非常慢。
  3. 后来我在 Visual Studio 中发现了一些类,例如 SqlDataSourceEnumerator。尽管这仅在某个服务正在运行并且某些端口打开时才有效。由于可能的安全问题和可能的不正确数据,我们最好不要这样做
  4. 我还看到一些人提到了一些其他的命名空间(一旦我再次找到它们就会在这里写出来),但是 msdn 表示这些命名空间我们将在不久的将来删除。

总结一下:我需要检索域上所有已安装的SQL-Server 实例,其版本在 2000 和 2008 R2 之间变化。

【问题讨论】:

  • 你试过NetServerEnum函数吗?
  • 还没有,这对我来说是新的。稍后我会研究一下并报告我的发现。
  • 好的,所以我使用了 NetServerEnum 函数。它确实返回了一些所需的数据,但看起来它仍然依赖于与 SqlDataSourceEnumerator 相同的东西。只是在本地网络上运行它,并没有提供网络上的所有 sql-server 实例。结果与 NetServerEnum 完全相同。
  • 正如你所说,很多人以前都问过这个问题,但不清楚你的问题为什么不同。您需要哪些使用您描述的方法无法找到的精确信息?如果选项 2 返回的“数据”比您需要的多,为什么不过滤或解析它以仅提供您确实需要的信息?
  • 嗨 Pondlife,感谢您的回复。问题在于选项 2 查询非常非常慢。完成大约需要 3-4 分钟。如果您需要查询大约 80 台机器,这不是很有用。返回更多数据的事实是它返回已安装产品列表中的所有内容,其中包含“sql”。而且我不确定是否可以让 wmi 查询更具体,同时仍然让它获取所有实例。其他主题没有为我提供正确解决方案的原因是它们已经过时、结果不可靠或仅适用于一两个特定版本

标签: c# sql-server wmi


【解决方案1】:

好的,我解决了这个问题。我做了几件事:

  • 首先我扫描域中的机器。
  • 检查SQLBrowser服务是否正在运行,如果没有,启动它!这是由位于system.ServiceProcessServiceController class 完成的
  • 启动所有 SQLBrowser 后,我使用 SqlDataSourceEnumerator 枚举所有实例。

对于那些对代码感兴趣的人:
注意:您需要网络管理员权限才能在远程机器上启动它。

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

然后这就是我用来检索实例的方法。

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

这可能不是最好的解决方案,有些人可能会觉得它有些脏。但就目前而言,这是我能得到的最好的解决方法。
希望这对以后遇到同样问题的人有所帮助。

【讨论】:

    【解决方案2】:

    我使用了这里的代码:http://msdn.microsoft.com/en-us/library/dd981032.aspx

    效果很好。唯一需要提及的是,这是针对 SQL 2005 - SQL 2008。您必须检查 ComputerManagement11 以获取 SQL 2012。

    【讨论】:

    • 我一直在寻找不需要 SQL 浏览器的解决方案。这很好用。谢谢 ! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 2013-05-08
    相关资源
    最近更新 更多