PID创建时间

时间:2016-01-10 13:08:25

标签: winapi

我一直在寻找一种方法来确定PID创建时间/最近声称的时间。我能够用NtQuerySystemInformation获得它,但是为了获得PID被声称的时间似乎是密集的。有没有非常快捷的方法来获取此信息?

我试过CreateToolhelp32Snapshot - > Process32First,这种方式非常快,但它没有给我PID创建时间。

由于

这是我从NtQuerySystemInformation获得的信息,下面是这个结构,它给了我UniqueProcessIdCreateTime

http://processhacker.sourceforge.net/doc/struct___s_y_s_t_e_m___p_r_o_c_e_s_s___i_n_f_o_r_m_a_t_i_o_n.html

_SYSTEM_PROCESS_INFORMATION Struct

ULONG   NextEntryOffset
ULONG   NumberOfThreads
LARGE_INTEGER   WorkingSetPrivateSize
ULONG   HardFaultCount
ULONG   NumberOfThreadsHighWatermark
ULONGLONG   CycleTime
LARGE_INTEGER   CreateTime
LARGE_INTEGER   UserTime
LARGE_INTEGER   KernelTime
UNICODE_STRING  ImageName
KPRIORITY   BasePriority
HANDLE  UniqueProcessId
HANDLE  InheritedFromUniqueProcessId
ULONG   HandleCount
ULONG   SessionId
ULONG_PTR   UniqueProcessKey
SIZE_T  PeakVirtualSize
SIZE_T  VirtualSize
ULONG   PageFaultCount
SIZE_T  PeakWorkingSetSize
SIZE_T  WorkingSetSize
SIZE_T  QuotaPeakPagedPoolUsage
SIZE_T  QuotaPagedPoolUsage
SIZE_T  QuotaPeakNonPagedPoolUsage
SIZE_T  QuotaNonPagedPoolUsage
SIZE_T  PagefileUsage
SIZE_T  PeakPagefileUsage
SIZE_T  PrivatePageCount
LARGE_INTEGER   ReadOperationCount
LARGE_INTEGER   WriteOperationCount
LARGE_INTEGER   OtherOperationCount
LARGE_INTEGER   ReadTransferCount
LARGE_INTEGER   WriteTransferCount
LARGE_INTEGER   OtherTransferCount
SYSTEM_THREAD_INFORMATION   Threads [1]

1 个答案:

答案 0 :(得分:4)

根据流程ID,使用OpenProcess()获取流程的HANDLE,然后使用GetProcessTimes()查询其时间。

BOOL GetProcessCreationTime(DWORD dwProcessId, LPFILETIME CreationTime)
{
    BOOL bResult = FALSE;
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId);
    if (hProcess)
    {
        FILETIME Ignore;
        bResult = GetProcessTimes(hProcess, CreationTime, &Ignore, &Ignore, &Ignore);
        CloseHandle(hProcess);
    }
    return bResult;
}

DWORD dwProcessId = ...;
FILETIME CreationTime;
if (GetProcessCreationTime(dwProcessId, &CreationTime))
{
    // use CreationTime as needed...
}

请注意,这只能在流程仍在运行时打开流程,或者流程已经终止但尚未完全关闭。

更新:如果您想使用NtQuerySystemInformation()代替GetProcessTimes(),则会更像是这样:

BOOL GetProcessCreationTime(DWORD dwProcessId, LPFILETIME CreationTime)
{
    typedef NTSTATUS (WINAPI *LPFN_NTQSI)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
    static LPFN_NTQSI lpNtQuerySystemInformation = NULL;

    if (!lpNtQuerySystemInformation)
    {
        lpNtQuerySystemInformation = (LPFN_NTQSI) GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation");
        if (!lpNtQuerySystemInformation)
            return FALSE;
    }

    _SYSTEM_PROCESS_INFORMATION *arr;
    ULONG ulSize = 1024;
    NTSTATUS status;

    do
    {
        arr = (_SYSTEM_PROCESS_INFORMATION*) LocalAlloc(LMEM_FIXED, ulSize);
        if (!arr)
            return FALSE;

        status = NtQuerySystemInformation(SystemProcessInformation, arr, ulSize, &ulSize); 
        if (NT_SUCCESS(status))
            break;

        LocalFree(arr);

        if (status != STATUS_INFO_LENGTH_MISMATCH)
            return FALSE;

        ulSize *= 2;
    }
    while (true);

    _SYSTEM_PROCESS_INFORMATION *process = arr;
    do
    {
        if (GetProcessId(process->UniqueProcessId) == dwProcessId)
        {
            CreationTime->dwLowDateTime = process->CreateTime.LowPart;
            CreationTime->dwHighDateTime = process->CreateTime.HighPart;
            LocalFree(arr);
            return TRUE;
        }

        if (process->NextEntryOffset == 0)
            break;

        process = (_SYSTEM_PROCESS_INFORMATION*) (((LPBYTE)process) + process->NextEntryOffset);
    }
    while (true);

    LocalFree(arr);
    return FALSE;
}