GetExitCodeProcess()返回128

时间:2008-09-26 12:25:08

标签: winapi dll process

我有一个DLL作为扩展加载到第三方父进程中。从这个DLL我使用CreateProcess API实例化外部进程(我自己的)。这在99.999%的情况下效果很好,但有时会突然失败并永久停止工作(也许重启父进程会解决这个问题,但这是不可取的,我不想在我解决问题之前建议这样做。)即使CreteProcess()没有报告错误并且GetExitCodeProcess()返回128,也不再调用外部进程来表示失败。这是我正在做的简化版本:

STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;

PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));

if(!CreateProcess(
    NULL,   // No module name (use command line). 
    "<my command line>",
    NULL,   // Process handle not inheritable. 
    NULL,   // Thread handle not inheritable. 
    FALSE,  // Set handle inheritance to FALSE. 
    CREATE_SUSPENDED,  // Create suspended.
    NULL,   // Use parent's environment block. 
    NULL,   // Use parent's starting directory. 
    &si,    // Pointer to STARTUPINFO structure.
    &pi))   // Pointer to PROCESS_INFORMATION structure.
{
    // Handle error.
}
else
{
    // Do something.

    // Resume the external process thread.
    DWORD resumeThreadResult = ResumeThread(pi.hThread);
    // ResumeThread() returns 1 which is OK
    // (it means that the thread was suspended but then restarted)

    // Wait for the external process to finish.
    DWORD waitForSingelObjectResult =  WaitForSingleObject(pi.hProcess, INFINITE);
    // WaitForSingleObject() returns 0 which is OK.

    // Get the exit code of the external process.
    DWORD exitCode;
    if(!GetExitCodeProcess(pi.hProcess, &exitCode))
    {
        // Handle error.
    }
    else
    {
        // There is no error but exitCode is 128, a value that
        // doesn't exist in the external process (and even if it
        // existed it doesn't matter as it isn't being invoked any more)
        // Error code 128 is ERROR_WAIT_NO_CHILDREN which would make some
        // sense *if* GetExitCodeProcess() returned FALSE and then I were to
        // get ERROR_WAIT_NO_CHILDREN with GetLastError()
    }

    // PROCESS_INFORMATION handles for process and thread are closed.
}

可以从Windows资源管理器或命令行手动调用外部进程,它可以自行启动。在执行任何实际工作之前,调用它会创建一个日志文件并记录一些有关它的信息。但是如上所述调用此日志信息根本不会出现,所以我假设外部进程的主线程永远不会进入main()(我现在正在测试这个假设。)

我至少可以做一件事来试图规避问题(不要启动线程暂停),但我首先要先了解失败的根源。有谁知道可能导致这种情况的原因以及如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

引自GetExitCodeProcess上的MSDN文章:

如果流程已终止,则可以返回以下终止状态:

  • 中指定的退出值 ExitProcess或TerminateProcess 功能
  • 来自的回报值 main或WinMain的功能 过程
  • 的例外值 未处理的异常导致了 终止的过程

鉴于您描述的情景,我认为最可能的原因是第三种:未处理的异常。查看您创建的流程的来源。

答案 1 :(得分:1)

查看桌面堆内存。

本质上,桌面堆问题归结为耗尽资源(例如,启动太多进程)。当您的应用程序用完这些资源时,其中一个症状是您将无法启动新进程,并且对CreateProcess的调用将失败并显示代码128.

请注意,您运行的上下文也有一些效果。例如,作为服务运行,与在控制台应用程序中测试代码相比,您将耗尽桌面堆。

这个post有很多关于桌面堆的好信息

Microsoft Support也有一些有用的信息。

答案 2 :(得分:0)

我可以从您的代码示例中找到2个问题

1.获取前2个参数的使用权,先使用creatprocess命令。硬编码路径并调用notepad.exe并查看是否出现。继续调整这个,直到你有记事本运行。

2.Contrary to your comment,如果您已将新进程的currentdirectory参数传递为NULL,它将使用进程的当前工作目录从父进程启动新进程,而不是父进程。

我认为由于无法在新路径中解析的dll依赖项,外部进程exe无法正常启动。

ps:在@ err,hr的调试器监视中,它会告诉你上一个错误代码的解释,