Я хотел сделать то же самое сам. Как упоминает Джим, можно получить адрес DllRegisterServer
и вызвать его, но это все равно изменяет ваш реестр различными записями. Если вы не хотите этого делать (например, у вас могут не быть необходимых прав для записи в реестр), есть другой способ.
Любая DLL, в которой находится один или несколько внутрипроцессных COM-объектов, должна предоставлять функцию DllGetClassObject
. Эта функция используется для получения экземпляра фабрики класса COM, который используется для создания объекта COM. Что вам нужно сделать, это:
- Загрузить библиотеку (DLL), в которой находится нужный COM-объект
- Найдите функцию
DllGetClassObject
- Вызовите
DllGetClassObject
, передав ему CLSID нужного COM-объекта, это вернет экземпляр IClassFactory
.
- Вызвать метод
CreateInstance
на фабрике классов, чтобы получить экземпляр COM-объекта.
- Приведите возвращенный объект к интерфейсу, который вы хотите использовать.
Обратите внимание, что при таком подходе есть драконы - это довольно низкий уровень. Если вы что-то не так сделаете, вы столкнетесь с нарушениями прав доступа или хуже. (Например, объявление вашего интерфейса должно точно соответствовать интерфейсу COM).
Я включил пример кода в gist , который вы могли бы использовать, если хотите пойти по этому пути.
Использование этого кода будет выглядеть примерно так:
// Load the library. You dispose this after you are finished with
// all of your COM objects.
var library = new LibraryModule();
library.Load("mylibrary.dll"); or whatever your dll is called
var clsid = new Guid("75E81043-CAD5-11D3-800D-00105A5E2FA0");
var myObject = (MyInterface)ComHelper.CreateInstance(library, clsid);
Просто обратите внимание, что если вы избавитесь от объекта LibraryModule
, это приведет к выгрузке DLL. В зависимости от ваших потребностей, вы можете просто присвоить значение статическому полю, чтобы оно существовало на протяжении всей жизни программы.