delphicommta

Out of process COM server in MTA issues


We have an out-of-process server running in MTA in a standalone application with UI.

Server is initialized in following way.

Scenario 1

initialization  begin
  CoUninitialize;
  CoUninitialize;
  CoUninitialize; //i have to call it three times to be able to initialize the MTA
  OLECHECK(ComObj.CoInitializeEx(nil, COINIT_MULTITHREADED));
  TAutoObjectFactory.Create(ComServer, MyServer,
     Class_MyServer,ciMultiInstance, tmFree);
end;

I just start the app and then close without any clients attached to it. During close following error occurs: Runtime error 216 at 00408A2E I'm not able to track it down it seems it is related with COM and I think that I'm doing something wrong.

The error does not occurs if I initialize the server in STA

initialization  begin
  TAutoObjectFactory.Create(ComServer, MyServer,
      Class_MyServer,ciMultiInstance, tmSingle);
end;

Scenario 2

I've also tried to create a thread in initialization section and create the server in Thread.execute and there is no error during close but clients does not discover the first instance of the server and instead activate another one.

procedure TDCOMThread.Execute;
var dwReturn:DWORD;
    Msg:TMsg;
    H:THandle;
begin
    OleCheck(ComObj.CoInitializeEx(nil, COINIT_MULTITHREADED));
    TAutoObjectFactory.Create(ComServer, MyServer,
         Class_MyServer,ciMultiInstance, tmFree);
    H:=EVentStop.Handle;
    while true do
    begin
       dwReturn:=MsgWaitForMultipleObjects(1,H,false,200,QS_ALLINPUT);
       case dwReturn of
         WAIT_OBJECT_0: break;
         (WAIT_OBJECT_0+1): begin
             while PeekMessage(msg,0,0,0,PM_REMOVE) do
               Dispatch(Msg);
         end;
         WAIT_TIMEOUT:begin
                           while PeekMessage(msg,0,0,0,PM_REMOVE) do
                             Dispatch(Msg);
                        if Terminated then
                         break;
                      end;
         WAIT_FAILED:begin
              break;
         end;
         WAIT_ABANDONED:
         begin
           break;
         end;

       end;
    end;
    CoUninitialize;
end;

Initialization section

 initialization  begin
        EVentStop:=Tevent.Create(true);
        EVentStop.ResetEvent;
        DThread:=TDCOMThread.Create(true);
        DThread.Resume;
    end;

Could you give any advice how to initialize Server in MTA and to bypass following issues:

  1. Do not gives error during close
  2. When server have been started manually clients to not launch another instance of the server application - this issues comes when i use a thread to init the server

Solution

  • In Scenario 2 try to call RegisterClassObject from newly created factory. In case of factory created in main thread - RegisterClassObject called automatically.