IApeClass *рас = 0;
HRESULT hr = CoGetClassObject(CLSID_Chimp, CLSCTX_REMOTE_SERVER, 0, IID_IApeClass, (void**) &pac);
то SCM со стороны клиента направит этот запрос в SCM на
IApeClass *рас = 0;
COSERVERINFO csi;
ZeroMemory(&csi, sizeof(csi));
csi.pwszName = OLESTR(www.dogs.com);
HRESULT hr = CoGetClassObject(CLSID_Chimp, CLSCTX_REMOTE_SERVER, &csi, IID_IApeClass, (void**)&pac);
то установка
Чаще встречается ситуация, когда клиенты не указывают явно свои предпочтения относительно хост-имени и месторасположения. Рассмотрим следующий вызов
IApeClass *pac = 0;
HRESULT hr = CoGetClassObject(CLSID_Chimp, CLSCTX_ALL, 0, IID_IApeClass, (void*)&pac);
Поскольку не указано никакого хост-имени, то SCM сначала будет искать в локальном реестре следующий ключ:
[HKCRAppID{27EE6A4F-DF65-11d0-8C5F-0080C7392SBA}]
Если этот ключ локально не доступен, COM обратится к хранилищу класса (
HKCRCLSID{27EE6A4F-DF65-11d0-8C5F-0080C73925BA}InprocServer32] @='C:somefile.dll'
Если этот ключ найден, класс будет активирован путем загрузки той DLL, которая указана в реестре. В противном случае SCM ищет подключ
HKCRCLSID{27EE6A4F-DF65-11d0-8C5F-0080C73925BA}InprocHandler32] @='C:somefile.dll'
Если класс имеет ключ дескриптора (
Только что описанный сценарий является корректным, если серверный процесс уже выполняется. Если, однако, SCM получает внепроцессный запрос на активацию, но под запрашиваемым CLSID не зарегистрировался ни один серверный процесс, то SCM запустит серверный процесс, который еще не запущен. COM поддерживает три модели для создания серверов: сервисы NT (
При создании серверного процесса SCM вначале проверяет, имеет ли AppID, соответствующий запрашиваемому классу, именованную величину
[HKCRAppID{27EE6A4D-DF65-11d0-8C5F-0080C73925BA} LocalService='apesvc'
Если это именованное значение имеется, то SCM использует NT Service Control Manager (диспетчер управления сервисами) для запуска той службы NT, которая указана в реестре (например,
[HKCRCLSID{27EE6A4F-DF65-11d0-8C5F-0080C73925BA}LocalServer32] @='C:somefile.exe'
Если этот ключ присутствует, то SCM применит для запуска серверного процесса API-функцию
[HKCRAppID{27EE6A4D-DF6S-11d0-8CSF-0080C73925BA}] DllSurrogate=''
Если величина, именованная
[HKCRAppID{27EE6A4D-DF65-11d0-8C5F-0080C7392SBA}] DllSurrogate='С:somefile.exe'
то SCM запустит указанный серверный процесс. В любом случае суррогатный процесс саморегистрируется библиотекой COM (и SCM) с помощью API-функции
HRESULT CoRegisterSurrogate([in] ISurrogate *psg);
Эта API-функция предполагает, что суррогатный процесс предоставляет реализацию интерфейса
[uuid(00000022-0000-0000-C000-000000000046), object] interface ISurrogate : IUnknown {
// SCM asking surrogate to load inprocess class object and
// call CoRegisterClassObject using REGCLS_SUSPENDED
// SCM просит суррогат загрузить внутрипроцессный
// объект класса и вызвать CoRegisterClassObject
// с флагом REGCLS_SUSPENDED
HRESULT LoadDllServer([in] REFCLSID rclsid);
// SCM asking surrogate to shut down
// SCM просит суррогат прекратить работу
HRESULT FreeSurrogate();
}