В этой статье я хотел бы дополнить и уточнить детали некоторых вопросов, описанных здесь
В .NET все-таки существует такая возможность, хоть она и требует некоторых неочевидных действий. Рассмотрим, что нужно сделать в данном случае.
Создать сборку с экспортируемыми COM-типами и зарегистрировать ее в реестре при помощи regasm. Здесь все выполняется точно так же, как для in-proc сервера — только тип выходного файла должен быть EXE. Если теперь попытаться создать COM-объект нашего типа, можно будет наблюдать интересный эффект — EXE-файл, который загружен в процесс как DLL ;)
Чтобы этого избежать, требуется дополнительное действие — добавить запись HKEY_CLASSES_ROOT/CLSID/<GUID класса>/LocalServer32, указывающую путь к нашей сборке. Такая запись нужна для каждого экспортируемого типа. Теперь, если попытаться создать COM-объект — наша сборка будет запущена в отдельном процессе. Однако, вскоре клиентский код выдаст ошибку — «Server execution failed». Причина — отсутствие фабрики объектов (COM class object) в нашей сборке. Каждый COM out-proc сервер должен зарегистрировать ее при запуске с помощью функции CoRegisterClassObject. Если этого не сделать в отведенное время, происходит ошибка.
К счастью, нам не придется возиться с P/Invoke — вся необходимая функциональность уже есть в классе RegistrationServices.
Регистрация фабрики объектов должна вызываться при запуске метода Main нашей сборки, и выглядит примерно так:
Этот код не совсем полон — необходима обработка блокировок сервера, которая будет автоматически закрывать процесс, когда не останется ни одного активного объекта. Однако, эта задача уже намного очевиднее в решении. Ее можно рассмотреть в отдельной статье, или перейти к другим интересным, но малоизвестным техникам:
Решать вам :)
Создание COM out-proc сервера
В .NET все-таки существует такая возможность, хоть она и требует некоторых неочевидных действий. Рассмотрим, что нужно сделать в данном случае.
Создать сборку с экспортируемыми COM-типами и зарегистрировать ее в реестре при помощи regasm. Здесь все выполняется точно так же, как для in-proc сервера — только тип выходного файла должен быть EXE. Если теперь попытаться создать COM-объект нашего типа, можно будет наблюдать интересный эффект — EXE-файл, который загружен в процесс как DLL ;)
Чтобы этого избежать, требуется дополнительное действие — добавить запись HKEY_CLASSES_ROOT/CLSID/<GUID класса>/LocalServer32, указывающую путь к нашей сборке. Такая запись нужна для каждого экспортируемого типа. Теперь, если попытаться создать COM-объект — наша сборка будет запущена в отдельном процессе. Однако, вскоре клиентский код выдаст ошибку — «Server execution failed». Причина — отсутствие фабрики объектов (COM class object) в нашей сборке. Каждый COM out-proc сервер должен зарегистрировать ее при запуске с помощью функции CoRegisterClassObject. Если этого не сделать в отведенное время, происходит ошибка.
К счастью, нам не придется возиться с P/Invoke — вся необходимая функциональность уже есть в классе RegistrationServices.
Регистрация фабрики объектов должна вызываться при запуске метода Main нашей сборки, и выглядит примерно так:
var rs = new RegistrationServices();
var cookie = rs.RegisterTypeForComClients(typeof(MyComType),
RegistrationClassContext.RemoteServer | RegistrationClassContext.LocalServer
| RegistrationClassContext.InProcessServer, RegistrationConnectionType.MultipleUse);
Application.Run();
rs.UnregisterTypeForComClients(cookie);
Этот код не совсем полон — необходима обработка блокировок сервера, которая будет автоматически закрывать процесс, когда не останется ни одного активного объекта. Однако, эта задача уже намного очевиднее в решении. Ее можно рассмотреть в отдельной статье, или перейти к другим интересным, но малоизвестным техникам:
- Передача управляемых методов для обратного вызова (callback)
- Экспорт управляемых методов в неуправляемый код
Решать вам :)