Recent

Author Topic: Read Windows Storage FileProperties  (Read 5005 times)

LazProgger

  • Jr. Member
  • **
  • Posts: 91
Re: Read Windows Storage FileProperties
« Reply #15 on: October 02, 2018, 03:32:39 pm »
One more question about the line:

Code: Pascal  [Select]
  1. CoInitialize(nil);

According to the Microsoft Documentation, this line is needed to initialize the COM library.

Do I have to ensure that this function is only called once? When reading out multiple files, could it be a problem to call it before each file processing or do I even have to?

For example, when putting the reading process into a function like GetFilePropertyX(AFileName: string): string, would it be a problem/performance hit to call CoInitialize each time calling the function from within the function? The backgound is: The function will not be called every time the program is started, so I do not want to call CoInitialize each time at program startup but only when needed.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 680
    • Lebeau Software
Re: Read Windows Storage FileProperties
« Reply #16 on: October 02, 2018, 07:41:41 pm »
One more question about the line:

Code: Pascal  [Select]
  1. CoInitialize(nil);

According to the Microsoft Documentation, this line is needed to initialize the COM library.

Do I have to ensure that this function is only called once? When reading out multiple files, could it be a problem to call it before each file processing or do I even have to?

It needs to be called once *per thread*.  It CAN be called more than once per thread, but if you try to specify a different threading model than the used by the 1st call, you will get an RPC_E_CHANGED_MODE error.  Every *successful* call to CoInitialize/Ex() requires a matching CoUninitialize() call.

For example, when putting the reading process into a function like GetFilePropertyX(AFileName: string): string, would it be a problem/performance hit to call CoInitialize each time calling the function from within the function?

Don't do that.  It is the calling thread's responsibility to initialize COM, not your function's.  And if the thread hasn't initialized COM yet when your function is called, and you silently initialize COM on the caller's behalf, unexpected things *may* happen later on in the thread's code long after your function has exited.  So just don't do it.  If COM hasn't been initialized yet, you should just fail and exit.  And document that your function requires COM to be initialized before called.

The backgound is: The function will not be called every time the program is started, so I do not want to call CoInitialize each time at program startup but only when needed.

The calling thread should initialize COM before calling your function.  If the thread doesn't call your function, it doesn't need to initialize COM.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

LazProgger

  • Jr. Member
  • **
  • Posts: 91
Re: Read Windows Storage FileProperties
« Reply #17 on: October 02, 2018, 08:00:55 pm »

It needs to be called once *per thread*.  It CAN be called more than once per thread, but if you try to specify a different threading model than the used by the 1st call, you will get an RPC_E_CHANGED_MODE error.  Every *successful* call to CoInitialize/Ex() requires a matching CoUninitialize() call.


Oh thanks.. The initial code had no CoUninitialize() call at all...

And if the thread hasn't initialized COM yet when your function is called, and you silently initialize COM on the caller's behalf, unexpected things *may* happen later on in the thread's code long after your function has exited.  So just don't do it.  If COM hasn't been initialized yet, you should just fail and exit.  And document that your function requires COM to be initialized before called.

Is there a way to check whether CoInitialize/Ex() has been called / is initialized?

ASerge

  • Hero Member
  • *****
  • Posts: 1420
Re: Read Windows Storage FileProperties
« Reply #18 on: October 02, 2018, 08:47:14 pm »
Is there a way to check whether CoInitialize/Ex() has been called / is initialized?
Code: Pascal  [Select]
  1. case CoInitialize(nil) of
  2.   S_OK: // First time
  3.     ;
  4.   S_FALSE: // Already initialized
  5.     CoUninitialize;
  6.   RPC_E_CHANGED_MODE: // Already initialized, but with differ concurrency model
  7.     ; // Ignore
  8. end;

LazProgger

  • Jr. Member
  • **
  • Posts: 91
Re: Read Windows Storage FileProperties
« Reply #19 on: October 02, 2018, 08:55:10 pm »
However, when checking it this way, I have again multiple CoInitialize calls and I thought I have to avoid that...

Thaddy

  • Hero Member
  • *****
  • Posts: 9282
Re: Read Windows Storage FileProperties
« Reply #20 on: October 02, 2018, 09:00:54 pm »
Well,
CoInitialize  and family should be called in an initialization and finalization part of a unit.
Anyway I just remembered I wrote or contributed to an article in UNDU about this around the beginning of this century.
I'll see if I can retrieve the code from somewhere.

Remy, I seem to remember there is indeed a per thread need, but depending on the COM model. (YOU remember UNDU for sure...  ;D)
Anyway a matching pair is required.
« Last Edit: October 02, 2018, 09:07:30 pm by Thaddy »
also related to equus asinus.

LazProgger

  • Jr. Member
  • **
  • Posts: 91
Re: Read Windows Storage FileProperties
« Reply #21 on: October 02, 2018, 09:09:15 pm »
That means, if I use CoInitialize from within a thread, I cannot do it in the initialization and finalization, because the unit is the main thread and not the thread in which the COM thing is used?

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 680
    • Lebeau Software
Re: Read Windows Storage FileProperties
« Reply #22 on: October 02, 2018, 09:16:19 pm »
CoInitialize  and family should be called in an initialization and finalization part of a unit.

That is actually a very bad idea.  Besides, that only (un)initializes the thread that is (un)initializing the unit, which may not be the same thread that is calling the function in question.

Remy, I seem to remember there is indeed a per thread need, but depending on the COM model.

COM is *always* initialized per-thread, regardless of the threading model.  A thread's threading model must be established before it can interact with any COM objects.  And a COM object has its own threading model, so the two models need to be known in order for COM to successfully interact (and know HOW to interact) between the thread and the COM object (direct access vs proxying, etc).

(YOU remember UNDU for sure...  ;D)

Never heard of it.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 680
    • Lebeau Software
Re: Read Windows Storage FileProperties
« Reply #23 on: October 02, 2018, 09:17:55 pm »
That means, if I use CoInitialize from within a thread, I cannot do it in the initialization and finalization, because the unit is the main thread and not the thread in which the COM thing is used?

Correct.  Every thread must call CoInitialize/Ex() and CoUninitialize() for itself.  This is why your function should NOT be (un)initializing COM at all, that is the thread's responsibility outside of your function.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)