У меня есть проект, который имеет много COM-библиотек, для требования я должен был отменить регистрацию COM-DLL, что я сделал, позвонив Regsvr32 -u
вариант а длл незарегистрированный.
Эта операция отмены регистрации, кажется, удаляет интерфейс, скажем ICommon
интерфейс, который делает другие объекты COM непригодными для использования.
это ICommon
Интерфейс реализован всеми другими компонентами COM, в сценарии реестра незарегистрированной COM Dll я не вижу кода, который удаляет это ICommon
интерфейс формы реестра, как это убирается.
Как информация интерфейса удаляется для данного CoClass
делает ли BEGIN_COM_MAP и COM_INTERFACE_ENTRY
играть какую-то роль?
COM изобилует проблемами с DLL Hell. Режим сбоя здесь заключается в том, что при удалении сервера также удаляются ключи из HKLM \ Software \ Classes \ Interface. Что говорит COM, какую реализацию прокси / заглушки следует использовать для маршалинга интерфейса через границы квартир. Ключ ProxyStubClsId32 для интерфейса идентифицирует прокси.
Так что это ломает любую клиентскую программу, которая использует другие COM-серверы, которые реализуют интерфейс, они больше не могут маршалировать интерфейс, и они умрут во время выполнения с E_NOINTERFACE. Сам по себе код ошибки сбивает с толку, можно предположить, что интерфейс как-то исчез, но на самом деле он жалуется на то, что COM-объект не реализует IMarshal. Последний вздох, когда COM не может найти ключ в реестре.
Не то, чтобы это обычно было трудно исправить, вам просто нужно перерегистрировать COM-сервер, который выходит из строя, он вернет ключ обратно.
Реальной защиты от этой потери не существует, вам придется реализовать сложную схему подсчета ссылок, которая записывает, сколько COM-серверов зависят от прокси-сервера, и удаляет только ключ (и DLL, если это настраиваемый прокси-сервер). когда он отсчитывает до нуля. Это было сделано, однако для того, чтобы он потерпел неудачу, требуется всего один установщик, который не покупается на схему, или неразумный Regsvr32.exe / u, выполненный из командной строки, как вы это сделали.
Да, эти элементы играют роль, как и библиотека типов, используемая regsvr32
,
Если ICommon
Интерфейс видим, просматривается библиотека типов компонента COM, этот тип рассматривается как «принадлежащий» компоненту, и regsvr32
Процесс добавляет этот компонент в качестве местоположения этого интерфейса. На удаление, наоборот, применяется. Так что пока ICommon
интерфейс по-прежнему используется, поскольку компонент, который рассматривается как «владелец» интерфейса, удаляется, регистрация интерфейса также удаляется. Новый «владелец» не устанавливается автоматически (или не регистрируется), это необходимо сделать, повторно зарегистрировав подходящий компонент.
Я рекомендую изолировать ICommon
интерфейс к одной библиотеке типов (компонент COM) и импортируйте эту библиотеку типов везде, где требуется интерфейс, тем самым обеспечивая единого «владельца» интерфейса.
Замечания: основываясь на опыте работы с некоторым унаследованным кодом (с этой проблемой), я должен был исправить это, быть очень осторожным при импорте или попытке повторно объявить системные интерфейсы (например, ISerializable
и т. д.) regsvr32
может также удалить их из реестра; вызывая мир боли. Удаление в этом случае почти разрушило всю систему.