QFileDialog / CoCreateInstance failed
-
Dear Qt Forum,
I work on a hefty desktop application where, on Windows, we need to use the native file open/save dialogs.
QFileDialog::getOpenFileName and getSaveFileName work correctly until, all of a sudden, they don't. And the message we get via qInstallMessageHandler is:
error: CoCreateInstance failed ()
error: CoCreateInstance failed (A dynamic link library (DLL) initialization routine failed.)Using QFileDialog::DontUseNativeDialog circumvents the problem. But that is not a valid solution in our case.
The problem happens randomly, but it seems to become much more likely when we open large documents on our app. I have been unable to figure out why. Probably because of the larger memory usage, the longer load times, or the larger number of elements in the UI (?).
I have digged deep on Google trying to find a solution, or somebody with a similar problem. I have found some threads reporting similar situations, and they all lead to my same conclusions: Something seems to be wrong/incompatible between the initialization or uninitialization of COM that Qt does, and what Windows expects for interfaces such as IID_IFileOpenDialog.
Is this a known issue? Has anybody come across this problem and/or have a solution here?
Thank you so very much in advance.
-
Hi and welcome to devnet,
One thing you can do is searching the bug report system.
-
I already tried bugreports.qt.io, with no luck.
Some more info: we have managed to reproduce the problem on win10 and win7.
Also, if instead of calling QFileDialog::... I try to CoCreateInstance an IID_IFileOpenDialog myself, I get (randomly) different results:
- Most of the times, it works, just as fine as QFileDialog itself.
- Sometimes I get an error saying that the class is not registered.
- Sometimes CoCreateInstance succeeeds but then ->Show on the returned interface returns with an abrupt user cancelled HRESULT.
There seems to be is some problem with COM, which is probably left in an odd status after some call somewhere (?).
What puzzles me the most is that I can consistently reproduce the problem (making it fail or not fail at will) depending on the memory usage of my application. This must be some sort of coincidence, but the symptoms can be reproduced in different computers.
Any help would be greatly appreciated.
-
Do you also have that with a minimal application ?
-
No, but I am reasonably sure that with a minimal application the problem wouldn't happen. As I mentioned, when our app loads a medium sized document, everything is fine. But as soon as we load a large document, the problem arises.
Some (possibly) related posts I've found on the Internet.
https://interest.qt-project.narkive.com/SOXPqFoA/windows-10-native-qfiledialog-qprinter-some-magic-application-hangs
https://lists.qt-project.org/pipermail/interest/2017-December/028960.html
https://stackoverflow.com/questions/46581081/qt-qfiledialog-create-unknown-com-object-and-security -
Hi, that first post you linked to I remember vaguely, it was about the different ways to initialize COM, which can be a problem if you're using a lot of frameworks like Qt, each using its own apartment style (STA, MTA, neutral etc.). So the failure could be due to some racing/threading condition, i.e. for a sufficiently large document some background COM stuff is messing with the QFileDialog's COM.
You could try to do what Rainer tries in that post, inserting an
CoUninitialize();
at the end of your main.cpp (or perhaps right before your call to QFileDialog, just guessing!)P.S. If you want to know more about COM apartments, Raymond Chen's most recent blog installment is what you need
-
Hello, and thank you for your replies.
First thing I tried when I saw that the Qt debug trace was mentioning CoCreateInstance was to uninit and reinit COM. But that didn't work. Then I found those threads online, brushed up my rusty knowledge on COM, and tried to carefully reproduce what is described in Rainer's post. But none of that worked.
At this point I have tried all combinations of things such as:
- Init COM myself at the beginning of the app.
- Uninit COM (and/or Ole) right before the call(s) to QFileDialog.
- Reinit right before said call(s).
- Uninit/reinit after the call(s).
...and nothing has fixed the problem. As a matter of fact, some of those combinations change the way in which the problem manifests, by making the app hang, instead of just not showing the dialog.
-
After some heavy detective work, I found the cause to my problem.
Cute Qt was free of guilt as expected, and this problem is very specific to our app. But I am leaving here a description of the resolution just in case somebody else ever hits something similar.
Our software makes use of Intel's Embree. And there is a pair of rtcNewDevice/rtcReleaseDevice calls to init and dispose of resources used by said library. We use Embree to build some raytracing structures that are indeed dependent on document size (number of objects/primitives). For some reason, starting at some (consistently the same) high number of objects, COM is affected badly within this sandwich of New/Release calls. The effect is that services such as Drag & Drop and very specially the native file Open/Save dialogs (wrapped by QFileDialog) are left inoperable.
In the very case of our app, creating and disposing of the Embree device only when it is about to be used, instead of once per document was enough to fix my problem. I haven't found anything online about this. But our particular problem is gone now.
Thank you for your replies!