/// <summary> /// Reads the guids from the enumerator. /// </summary> private List <Guid> ReadClasses(OpcRcw.Comn.IOPCEnumGUID enumerator) { List <Guid> guids = new List <Guid>(); int fetched = 0; Guid[] buffer = new Guid[10]; do { try { IntPtr pGuids = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(Guid)) * buffer.Length); try { enumerator.Next(buffer.Length, pGuids, out fetched); if (fetched > 0) { IntPtr pos = pGuids; for (int ii = 0; ii < fetched; ii++) { buffer[ii] = (Guid)Marshal.PtrToStructure(pos, typeof(Guid)); pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(Guid))); guids.Add(buffer[ii]); } } } finally { Marshal.FreeCoTaskMem(pGuids); } } catch { break; } }while (fetched > 0); return(guids); }
/// <summary> /// Returns a list of servers that support the specified specification. /// </summary> public ServerDescription[] GetAvailableServers(params Guid[] catids) { // enumerate servers on specified machine. try { // get list of servers in the specified specification. OpcRcw.Comn.IOPCEnumGUID enumerator = null; m_server.EnumClassesOfCategories( catids.Length, catids, 0, null, out enumerator); // read clsids. List <Guid> clsids = ReadClasses(enumerator); // release enumerator object. Utils.ReleaseServer(enumerator); enumerator = null; // fetch class descriptions. ServerDescription[] servers = new ServerDescription[clsids.Count]; for (int ii = 0; ii < servers.Length; ii++) { servers[ii] = ReadServerDetails(clsids[ii]); } return(servers); } catch (Exception e) { throw Utils.CreateComException(e, ResultIds.E_FAIL, "Could not enumerate COM servers."); } }