2

With Delphi, how can I create a (Windows) console application that has a main thread that is initialized as COINIT_MULTITHREADED?

If I call CoInitializeEx(nil, COINIT_MULTITHREADED) in the very first statement, I get a HRESULT 0x80010106 (Cannot change thread mode after it is set), so obviously some previously running code already called CoInitialize/Ex.

How can I get the main thread to be COINIT_MULTITHREADED?

Martin
  • 1,986
  • 15
  • 32

1 Answers1

5

One of the units included in your program as a result of your uses clause has already initialized COM in its unit initialization section.

You need to identify that unit, and remove it from your program.

Consider this program:

{$APPTYPE CONSOLE}

uses
  ActiveX,
  ComObj;

begin
  Writeln(CoInitializeEx(nil, COINIT_MULTITHREADED));
end.

The output is 0 which demonstrates that an empty console application does not initialize COM.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    I think that means "you can't, look for a workaround". E.g. start a new thread. – Martin Aug 02 '19 at 11:29
  • Exactly. Not sure what that workaround should be, depends on whether or not you can find a way to sidestep the COM initialization performed in the other unit. That would be where I would start. – David Heffernan Aug 02 '19 at 11:30
  • The workaround? In the main thread I start a new thread, initialize it as MTA, do all the stuff there, and have the main thread wait for that thread. Of course this only works if I don't use something in that thread that requires STA. Maybe not nice, but I can't see why this shouldn't work. I won't use it in production code, though, promise :) – Martin Aug 02 '19 at 11:34
  • It works fine. But I'd still question using code that initialises COM behind your back. In your shoes I'd be trying to work out what has done that. – David Heffernan Aug 02 '19 at 12:05
  • 1
    Maybe you can initialize COM in the initialization section of a unit that you include as the first unit in your project. Maybe that won't solve the problem, but then your code gets to set the thread mode, and the other code will throw the exception. That may at least provide you an easy way to figure out what code causes the problem. – GolezTrol Aug 03 '19 at 23:12