什么可能导致ShellExecute返回SE_ERR_OOM(错误8)?

时间:2014-08-10 21:26:25

标签: c++ windows winapi out-of-memory shellexecute

我经常从本机C ++ / Win32应用程序调用ShellExecute来执行最终用户从GUI选择的任何shell项目。项目是可执行文件/脚本或链接(.lnk)。在某些对我来说模糊不清的情况下,以下函数有时会返回8SE_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文档),而不是因为个人选择

到目前为止对该错误的观察:

  • 很少见
  • 仅在一次或多次休眠后发生(我的应用程序总是在我的笔记本电脑上运行而且经常使用它)
  • 致电ShellExecute后立即致电GetLastError,始终返回0
  • 据我记忆,它总是在尝试执行.lnk文件时发生,但并不总是同一个文件
  • 快速查看在计算机上运行的Process Explorer(sysinternals.com)并未显示任何内存使用高峰
  • 修改:我在发布此处之前做了最后一次测试,连续200次致电doExecute。所有过程都是在没有错误的情况下产生的。

1 个答案:

答案 0 :(得分:1)

经过长时间的测试后,根据@DavidHeffernan和@RossRidge的建议,在我对代码进行了一些更改之后,错误再也没有发生了。虽然我不能真正认为这是一个明确的答案本身,因为我仍然不知道究竟发生了什么,我到目前为止还没有能够重现这个错误。

应用修改:

  • ShellExecute替换ShellExecuteEx来电。
  • 为每个新主题调用CoInitializeEx一次,而不是CoUninitialize个反对。但保留了以下嵌套CoInitializeEx - CoUninitialize对。

编辑:如果有人需要,只是为了确认问题不再发生,即使经过几个月的测试,也应用了这些修改。