什么可能导致ShellExecute返回SE_ERR_OOM(错误8)
What could possibly cause ShellExecute to return SE_ERR_OOM (error 8)?
我经常从本地c++/Win32应用程序调用ShellExecute来执行最终用户从GUI中选择的任何shell项。项要么是可执行文件/脚本,要么是链接(. link)。在一些对我来说仍然模糊的条件下,下面的函数有时返回8
(SE_ERR_OOM
错误;只有非常简短的记录)。因此,该项不会被执行。什么可能导致这个错误?
int doExecute(LPCTSTR file, LPCTSTR args, LPCTSTR workDir)
{
assert(file && *file);
HRESULT hRes = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
assert(hRes == S_OK || hRes == S_FALSE);
int code = (int)ShellExecute(NULL, NULL, file, args, workDir, SW_SHOWNORMAL);
doLog("ShellExecute returned: %d, %u", code, GetLastError()); // EDIT
CoUninitialize();
return code;
}
的背景:
- Windows8 64位,应用程序是32位,无法在任何其他机器上尝试
- 应用是多线程的
- 根据设计,总是专门创建一个新线程来执行此调用
- 这段代码中的断言在我的调试会话期间从未中断
- 应用程序本身不直接使用COM,但可能不得不调用Win32 api间接使用它,因为它与shell交互非常频繁。在这些情况下,COM总是使用与上面显示的相同的标志进行初始化。
- 传递给
CoInitializeEx
的标志是在MSDN推荐后盲目选择的(参见ShellExecute文档),而不是因为个人选择
到目前为止关于bug的观察:
- 很少
- 它只发生在一次或几次休眠后(我的应用程序总是在我的笔记本电脑上运行,我经常使用它)
- 调用
ShellExecute
后立即调用GetLastError总是返回0
- 据我所知,它总是发生,而试图执行
.lnk
文件,但并不总是相同的文件 - 快速查看在机器上运行的
Process Explorer
(sysinternals.com)没有显示任何内存使用峰值 - 编辑:我通过连续200次调用
doExecute
在这里发布之前做了最后一次测试。
经过相当长时间的测试,在我按照@DavidHeffernan和@RossRidge的建议对代码进行了一些更改之后,这个错误再也没有发生过。虽然我不能真正认为这是一个明确的答案本身,因为我仍然不知道到底发生了什么,我还没有能够重现到目前为止的错误。
修改应用:
- 将
ShellExecute
呼叫替换为ShellExecuteEx
。 - 对每个新线程调用
CoInitializeEx
一次,不调用对应的CoUninitialize
。但保留了以下嵌套的CoInitializeEx
-CoUninitialize
对。
编辑:以防有人需要它,只是为了确认问题不再发生,即使经过几个月的测试,有这些修改应用。
相关文章:
- 编译 C++ AMQP-CPP 演示程序 Err,Make Err
- Pc Lint,如何使用 init() 抑制类的 err 613(可能使用空 ponter)
- SDL Hello World 程序不输出消息
- 如何在 Linux 中将孩子的进程 std (out / err) 设置为父级
- 无法调用另一个类-ERR-未解析的外部符号
- Qt 音频输入错误 : pcm_params.c :2348 : sndrv_pcm_hw_params: L'assertion « err >= 0
- 确定外部进程的主线程id (ReadProcessMemory - Err 299)
- visual studio 2008 sp1 std::string::c_str() err
- 如何解决桨v0.8.0b上的"cudaSuccess = err (0 vs. 8)"错误?
- Android JNI中的OOM错误
- 为什么c++向量会导致oom杀手
- 内存泄漏,在 OOM 时不会崩溃,也不会显示在地块/瓦尔格林德