Опубликован: 11.05.2007 | Доступ: свободный | Студентов: 1692 / 229 | Оценка: 4.36 / 4.25 | Длительность: 16:06:00
Дополнительный материал 1:

Приложение I. Администрирование каталога COM+

< Лекция 12 || Дополнительный материал 1 || Дополнительный материал 2 >

Приложение I. Администрирование каталога COM+

Текущая на момент написания курса версия .NET Framework 2.0 не содержала штатных средств администрирования каталога компонент COM+, отличных от внешней программы регистрации и удаления компонент COM+ regsvcs.exe. В частности, в библиотеке классов .NET Framework нет методов для подписки компонент на события COM+. Ниже представлено одно из возможных решений этой досадной проблемы.

Первоначально необходимо создать сборку .NET с типами из библиотеки администрирования COM и COM+, которая расположена в %systemroot%\system32\com\comadmin.dll. Это можно сделать следующими двумя командами.

sn /k comadmin.snk
tlbimp %Systemroot%\system32\com\comadmin.dll /keyfile:comadmin.snk 
                /out:interop.comadmin.dll /namespace:ComAdmin

Первая команда создает пару ключей для создаваемой сборки, вторая импортирует типы из COM библиотеки и создает подписанную сборку CLR с именем interop.comadmin.dll, включая импортированные типы в пространство имен с именем ComAdmin.

Для удобного использования классов созданной сборки interop.comadmin следует реализовать некоторый промежуточный интерфейс для администрирования каталога COM+. Данный каталог представляет собой древовидное хранилище информации о приложениях COM+, входящих в их состав компонентах и ролях пользователей. На рисунке I.I показана основная часть структуры каталога COM+, в скобках указаны имена соответствующих коллекций каталога.

Упрощенная структура каталога COM+

Рис. I.1. Упрощенная структура каталога COM+

Приведенные в курсе примеры используют следующий вспомогательный класс LceUtils для создания постоянной подписки. Далее идет полное описание этого класса.

// Файл SevaComLCE.cs
using System;
using ComAdmin;
namespace Seva.ComUtils
{
    public static class LceUtils
    {
        // Создание постоянной подписки
        public static void PermanentSubscription(string appName, 
            string subscriberName, string eventGuid, string interfaceGuid)
        {
            // Создание объекта для доступа к каталогу COM+ 
            COMAdminCatalog catalog = new ComAdmin.COMAdminCatalogClass(); 

            ICatalogObject CatalogObject = null;
            ICatalogCollection CompCollection = null, SubCollection = null;

            // Получение списка приложений COM+ 
            ICatalogCollection AppCollection = (ICatalogCollection) 
                catalog.GetCollection("Applications");
            AppCollection.Populate();

            // Поиск нужного приложения по его имени
            for (int Counter = 0; Counter < AppCollection.Count; Counter++)
            {
                CatalogObject = (ICatalogObject) AppCollection.get_Item(Counter);
                if ((String)CatalogObject.Name == appName)
                {
                    // Получение компонент приложения
                    CompCollection = (ICatalogCollection) 
                        AppCollection.GetCollection("Components",
                                                 CatalogObject.Key);
                    CompCollection.Populate();
                    break;
                }
            }
            if (CompCollection == null)
            {
                throw new ApplicationException(
                    String.Format("COM+ Application not found : [{0}]", appName));
            }
            // Поиск указанной компоненты
            for (int Counter = 0; Counter < CompCollection.Count; Counter++)
            {
                CatalogObject = (ICatalogObject) CompCollection.get_Item(Counter);
                if ((String)CatalogObject.Name == subscriberName)
                {
                    // Получение списка подписок компоненты
                    SubCollection = (ICatalogCollection)
                    CompCollection.GetCollection(
                        "SubscriptionsForComponent", CatalogObject.Key);
                    SubCollection.Populate();
                    break;
                }
            }
            if (SubCollection == null)             
            {
                throw new ApplicationException(
                    String.Format("Component not found : [{0}]", subscriberName));
            }
            // Создание подписки
            CatalogObject = (ICatalogObject)SubCollection.Add();
            CatalogObject.set_Value("EventCLSID", "{" + eventGuid + "}");
            CatalogObject.set_Value("Name", "Permanent Subscription");            
            CatalogObject.set_Value("InterfaceID", "{" + interfaceGuid + "}");
            CatalogObject.set_Value("Enabled", true);
            // Сохранение изменений
            SubCollection.SaveChanges();
        } // Subscribe
     
    } //LceUtils

} // Seva.ComUtils
< Лекция 12 || Дополнительный материал 1 || Дополнительный материал 2 >