{"id":571,"date":"2010-01-18T20:19:30","date_gmt":"2010-01-18T19:19:30","guid":{"rendered":"http:\/\/blog.m-ri.de\/?p=571"},"modified":"2010-01-16T12:22:53","modified_gmt":"2010-01-16T11:22:53","slug":"alle-sql-server-enumerieren-mit-den-ole-db-enumeratoren","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2010\/01\/18\/alle-sql-server-enumerieren-mit-den-ole-db-enumeratoren\/","title":{"rendered":"Alle SQL Server enumerieren mit den OLE-DB Enumeratoren"},"content":{"rendered":"<p>Wie bekommt man eigentlich einfach eine Liste aller verf\u00fcgbaren SQL-Server im Netz?<\/p>\n<p>In der MSDN findet sich schnell ein Artikel <a href=\"http:\/\/support.microsoft.com\/kb\/287737\/en-us\">How to enumerate available instances of SQL Server by using the SQLDMO components<\/a>. Allerdings ist dieser Artikel wenig n\u00fctzlich, denn SQL-DMO findet man nur noch selten auf einem Rechner.<\/p>\n<p>Dabei ist es doch relativ einfach, denn OLE-DB sieht hierf\u00fcr Enumeratoren vor. Aber auch die sind nicht sonderlich gut dokumentiert. In der SQL-2000 Server Doku findet sich noch ein Eintrag f\u00fcr den <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa198369(SQL.80).aspx\">SQLOLEDB Enumerator<\/a>. F\u00fcr den neuen nativen OLE-DB Clienst f\u00fcr den SQL-Server finde ich nichts mehr dazu.<\/p>\n<p>ATL stellt direkt Klassen zur Verf\u00fcgung, die die Nutzung von Enumeratoren zu einem Kinderspiel machen.<\/p>\n<p>Anbei ein Codeschnippsel der alle bekannten MS-SQL Server enumeriert. Ich beginne dabei mit dem neuesten Client (2008) und gehe die Schleife weiter bis zum \u00e4ltesten Server Client (2000).<br \/>\nWird ein Enumerator gefunden, und dieser lieferte Ergebnisse, dann wird die Schleife abgebrochen. Denn alle Enumeratoren liefern im Allgemeinen das gleiche Ergebnis.<\/p>\n<p>Code:<\/p>\n<pre lang=\"cpp\">\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\/\/ Main function to enumerate all servers with the appropriate\r\n\/\/ known enumerators.\r\n\r\ntypedef std::set<CString>  TSET_CString;\r\n\r\nvoid EnumSQLServer(TSET_CString &setSQLServer)\r\n{\r\n  \/\/ We may need the local server name. \r\n  \/\/ We replace the token (local) with the current computer name.\r\n  CString strCompLocal;\r\n  DWORD dwLen = MAX_COMPUTERNAME_LENGTH+1;\r\n  ::GetComputerName(CStrBuf(strCompLocal,dwLen),&dwLen);\r\n\r\n  \/\/ Loop over all enumerators we know\r\n  static const PCWSTR aEnumerator[] =\r\n  {\r\n    L\"SQLNCLI10 Enumerator\",    \/\/ SQL 2008\r\n    L\"SQLNCLI Enumerator\",      \/\/ SQL 2005\r\n    L\"SQLOLEDB Enumerator\"      \/\/ SQL 2000\r\n  };\r\n\r\n  \/\/ Try all enumerators\r\n  for (int i=0; i < _countof(aEnumerator); ++i)\r\n  {\r\n    \/\/ Check if we have an enumerator\r\n    bool bFoundAny = false;\r\n    HRESULT hr;\r\n    CLSID clsid;\r\n    hr = CLSIDFromProgID(aEnumerator[i],&#038;clsid);\r\n    if (SUCCEEDED(hr))\r\n    {\r\n      \/\/ Open enumerator and loop over all entries\r\n      CEnumerator enumrator;\r\n      hr = enumrator.Open(&#038;clsid);\r\n      if (SUCCEEDED(hr))\r\n      {\r\n        while ((hr=enumrator.MoveNext())==S_OK)\r\n        {\r\n          CString strServerName(enumrator.m_szName);\r\n\r\n          \/\/ Skip empty server names \r\n          \/\/ (older enumerators return sometimes an empty name)\r\n          if (strServerName.IsEmpty())\r\n            continue;\r\n\r\n          \/\/ Some enumerators return (local) for a local main\r\n          \/\/ SQL server instance\r\n          if (strServerName.CompareNoCase(_T(\"(local)\"))==0)\r\n          {\r\n            ATLTRACE(__FUNCTION__ \" found local computer\\n\");\r\n            strServerName = strCompLocal;\r\n          }\r\n\r\n          \/\/ get uppercase server name\r\n          strServerName.MakeUpper();\r\n\r\n          \/\/ Insert in list and avoid duplicates with this, if\r\n          \/\/ developer decides not to break the loop after the first\r\n          \/\/ enumerator.\r\n          if (setSQLServer.insert(strServerName).second)\r\n            ATLTRACE(__FUNCTION__ \" found server %s\\n\",\r\n                  CT2A(strServerName.GetString()));\r\n          bFoundAny = true;\r\n        }\r\n      }\r\n\r\n      \/\/ After we have found data in one enumerator. There is no need\r\n      \/\/ to do this again.\r\n      \/\/ But a developer might decide to do this for every enumerator\r\n      if (bFoundAny)\r\n        break;\r\n    }\r\n  }\r\n}\r\n\r\n<\/pre>\n<p>Ein lauff\u00e4higes Projekt kann man hier herunterladen: <a href=\"http:\/\/blog.m-ri.de\/wp-content\/uploads\/2010\/01\/EnumSQLServer.zip\">EnumSQLServer.zip<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wie bekommt man eigentlich einfach eine Liste aller verf\u00fcgbaren SQL-Server im Netz? In der MSDN findet sich schnell ein Artikel How to enumerate available instances of SQL Server by using the SQLDMO components. Allerdings ist dieser Artikel wenig n\u00fctzlich, denn SQL-DMO findet man nur noch selten auf einem Rechner. Dabei ist es doch relativ einfach, &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2010\/01\/18\/alle-sql-server-enumerieren-mit-den-ole-db-enumeratoren\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eAlle SQL Server enumerieren mit den OLE-DB Enumeratoren\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[25,3,15,2],"tags":[366,159,214,213,216,359,215,217,59],"class_list":["post-571","post","type-post","status-publish","format-standard","hentry","category-atl","category-programmieren","category-sql","category-windows-api","tag-atl","tag-ms-sql","tag-ole-db","tag-oledb","tag-sq-2005","tag-sql","tag-sql-2000","tag-sql-2008","tag-win32"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/571","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/comments?post=571"}],"version-history":[{"count":0,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/571\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=571"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=571"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=571"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}