为什么在多次或仅一次调用 CreateProcess 时会恰好泄漏两个句柄?

Why do I leak exactly two handles when calling CreateProcess multiple times or just once?

根据 GetProcessHandleCount,我在调用 CreateProcess 时丢失了两个句柄。请看下面的最小示例,它将创建一个子进程。在创建子进程之前,检查句柄的数量。然后关闭 PROCESS_INFORMATION 结构中返回的子进程句柄,然后再次计算句柄。我得到 2 句柄的差异 - 有人知道为什么吗?

同样有趣:如果我在下面示例的 for 循环中创建多个子进程,我也会 "leak" 正好两个句柄。

编辑:请注意,在 StartupInformation 结构中没有句柄被返回,所以没有什么可以关闭的。

谁能给我解释一下这两个手柄的区别?

#include <windows.h>
#include <tchar.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
    std::wstring commandLine = L"C:\windows\system32\cmd.exe";

    BOOL closedHT = FALSE;
    BOOL closedHP = FALSE;
    BOOL createdProcess = FALSE;

    // Count handles before creating child processes:
    HANDLE hCurrent = GetCurrentProcess();
    DWORD hCountBefore = 0;
    ::GetProcessHandleCount(hCurrent, &hCountBefore);

    // Create one child-processes:
    for (size_t i = 0; i < 1; i++)
    {
        STARTUPINFO startupInfo;
        ::ZeroMemory(&startupInfo, sizeof(startupInfo));

        PROCESS_INFORMATION procInfo;
        ::ZeroMemory(&procInfo, sizeof(procInfo));

        createdProcess = ::CreateProcess(NULL, (LPWSTR)commandLine.c_str(), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &procInfo);
        closedHP = ::CloseHandle(procInfo.hProcess);
        closedHT = ::CloseHandle(procInfo.hThread);
    }

    // And calculate the difference of handles:
    DWORD hCountAfter = 0;
    ::GetProcessHandleCount(hCurrent, &hCountAfter);
    DWORD diff = hCountAfter - hCountBefore;

    if (createdProcess && closedHP && closedHT && diff != 0)
    {
        std::wcout << L"lost handles??: " << diff << std::endl;
    }
    else
    {
        std::wcout << L"Nothing got lost" << std::endl;
    }

    return 0;
}

UKMonkey 是对的,它将加载 apphelp.dll,这将打开两个句柄:

查看以下两个屏幕截图,显示加载/打开的 dll 和句柄:

通过调用 LoadLibrary 加载 dll 本身将打开 SESSION MANAGER 的句柄,第一次调用 CreateProcess 将打开 Custom Locale 的句柄。