Asked by:
MS C++ executable just started failing

Question
-
I suddenly have a failure on an application has been working for 15 years, and the executable has not been recompiled for the last 6 months.
I am using:
1. Operating System: Windows 10
2. Compiler: Microsoft Visual Studio 2010
3. Code: Microsoft C++ MFC SDK
Suddenly, all saves fail in a Microsoft procedure CRecentFileList [see Microsoft code below]. It doesn't fail until after a print to screen. This is true of executables from 6 months ago that have been working un until now. and happens on different Windows 10 machines.
Questions:
1. Is there any way to fix this?
2. If I can't fix it, can I eliminate: ENSURE(SUCCEEDED(hr)); Add(psi, strAppID); so that it doesn't fail?
3. I tried this, and it doesn't recognize that I changed it. How do I get the compiler to recompile and recognize that I chaned filelist.cpp?
4. Would it help to go to Microsoft Visual Studio 2015?
---------------------------------------------------
MICROSOFT CODE WITH CALL....
The failure is in the code below.
Fails in call to afxGlobalData.ShellCreateItemFromParsingName below.
Returns: hr = 0x800401f0 CoInitialize has not been called. (normally hr==S_OK)
Called with: lpWPath = 0x00a5eee0 "C:\winfree\_small.fre"
filelist.cpp:
void CRecentFileList::Add(LPCTSTR lpszPathName, LPCTSTR lpszAppID)
{
if (!afxGlobalData.bIsWindows7)
{
Add(lpszPathName);
return;
}
CString strAppID = lpszAppID == NULL ? _T("") : lpszAppID;
#if (WINVER >= 0x0601)
ASSERT(AfxIsValidString(lpszPathName));
Add(lpszPathName);
HRESULT hr = S_OK;
CComPtr<IShellItem> psi = NULL;
#ifdef UNICODE
hr = afxGlobalData.ShellCreateItemFromParsingName(lpszPathName, NULL, IID_IShellItem, reinterpret_cast<void**>(&psi));
#else
{
USES_CONVERSION;
LPOLESTR lpWPath = A2W(lpszPathName);
hr = afxGlobalData.ShellCreateItemFromParsingName(lpWPath, NULL, IID_IShellItem, (LPVOID*)&psi); <---------------------- Point of failure
}
#endif
ENSURE(SUCCEEDED(hr));
Add(psi, strAppID);
#endif
}Sunday, October 23, 2016 7:21 PM
All replies
-
Hi Dick Stone,
thanks for posting here.
1. Is there any way to fix this?
According to the error message, you have missed CoInitialize somewhere. You need to call the CoInitialize function in order to initialize the COM library for your application's thread. And notes that new applications should call CoInitializeEx instead of CoInitialize. If you want to use the Windows Runtime, you must call Windows::Foundation::Initialize instead. Please show us how do you call CRecentFileList::Add method. So that we could find the root cause. 2. If I can't fix it, can I eliminate: ENSURE(SUCCEEDED(hr)); Add(psi, strAppID); so that it doesn't fail?
The ENSURE(SUCCEEDED(hr)); won't prevent the failure. It will still cause the problem if you miss the CoInitialize .
3. I tried this, and it doesn't recognize that I changed it. How do I get the compiler to recompile and recognize that I chaned filelist.cpp?You could would click “Clean”, and then “Build” the app, or click “Rebuild”.
Here is a document you could refer to.
https://msdn.microsoft.com/en-us/library/5tdasz7h.aspx?f=255&MSPPError=-2147217396
4. Would it help to go to Microsoft Visual Studio 2015?You could download and try it.
Here is a similar case for you, maybe could be help of you.
Best Regards,
Sera YuMSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.- Proposed as answer by Baron Bi Friday, October 28, 2016 8:30 AM
Tuesday, October 25, 2016 8:51 AM -
I looked at the reference to the other problem. It appears to be exactly what happens to me, event upgrading from C++ 6. I don't understand why it took 5 years to manifest, though.
I tried adding the initialization. But I got (for either CoInitialize or CoInitializeEx:
- 2>c:\wfree\winfree.cpp(712): error C2660: 'CoInitialize' : function does not take 0 arguments
When I look at the definition, it's:
- __checkReturn WINOLEAPI CoInitialize(__in_opt LPVOID pvReserved);
What am I missing for an argument.
Tuesday, October 25, 2016 3:58 PM -
-
WORKING!
Thanks!
Tuesday, October 25, 2016 6:05 PM -
Then please mark the thread answered.
- Edited by Barry-Schwarz Tuesday, October 25, 2016 10:14 PM
Tuesday, October 25, 2016 6:59 PM -
Unfortunately this text does really answer the reason of the problem. I have the same problem now with mfc opening repeatedly documents (mdi OpenDocumentFile) and close them after some seconds (OnCloseDocument). Everytime it comes to this code and about 10 times with result S_OK and by unknown reason at random time it gets error Coinitialize not called without any differences in the steps done before.
1. the error occurs in mfc internal code CRecentFileList, so if normally there should not be a need to call CoInitialize self. It should have been done by mfc Startup of Visual Studio 10 code (and probably is done in afxglobals during startup).
2. after starting the application the open file dialog was used which probably also called the CoInitialize that the common dialog works (maybe this file dialog call is in an other thread independent to the current problem in main thread)
3. how could it be that this ShellCreateItemFromParsingName operation 10 times or more runs well without complaining about missing CoInitialize and then stops with this problem. (not to mentioned that the path Parameter is valid).
when ignoring the assertation in debugger it opens the document well. The problem at this location might only cause that the path was not added to the recent file list menu.
4. couldn't it cause problems if calling CoInitialize self and mfc calls it too (maybe even with different parameters). mfc globals self has a local variable that ensures that itself calls CoInitialize only once .
It is a mystery why the error happens.Regards
GünterFriday, January 4, 2019 10:35 AM -
The MFC framework does not automatically call CoInitialize(Ex) to initialize COM. The wizard generated code for an MDI or SDI application will include a call to AfxOleInit() in the generated override of CWinApp:;InitInstance. For example, see CWinApp::InitInstance
Friday, January 4, 2019 1:22 PM -
Some things aren't always obvious with COM.
For example, even if a thread does not initialize COM if another thread enters the MTA when it initializes COM then the first thread is placed in something called the implicit MTA, even though it did not initialize COM. So its then possible for functions on the first thread that use COM to succeed. And COM will spin up a new thread in an STA if the first thread in the implicit MTA instantiates an STA COM object. When the second thread that called CoInitializeEx to enter the MTA exits, the MTA (and the implicit MTA) are torn down. Suddenly COM calls on the first thread will fail.
Friday, January 4, 2019 6:23 PM