1. #include <iostream>
    2. #include <windows.h>
    3. // 编写函数打印指定线程的创建时间,要求接受一个线程句柄
    4. VOID GetThreadCreateTime(HANDLE Thread)
    5. {
    6. // 创建结构体用于保存获取到的和线程相关的时间戳
    7. FILETIME CreateTime{}, ExitTime{};
    8. FILETIME UserTime{}, KernelTime{};
    9. // 使用函数获取到线程的创建时间
    10. GetThreadTimes(Thread, &CreateTime, &ExitTime, &UserTime, &KernelTime);
    11. // 将时间戳转换为当前时区表示的时间
    12. FILETIME LocalTime{};
    13. FileTimeToLocalFileTime(&CreateTime, &LocalTime);
    14. // 将时间戳转换为时间结构体
    15. SYSTEMTIME SystemTime{};
    16. FileTimeToSystemTime(&LocalTime, &SystemTime);
    17. // 输出指定线程的创建时间
    18. printf("%d 时 %d 分 %d 秒\n", SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
    19. }
    20. // 一个线程,输出参数指定的线程的创建时间
    21. DWORD CALLBACK WorkerThread(LPVOID Paramater)
    22. {
    23. // 通过强制类型转换获取到传入的线程句柄
    24. HANDLE Thread = (HANDLE)Paramater;
    25. // 在当前线程中得到的实际上是主线程的伪句柄,也就是 -2,-2永远代表的都是当前的
    26. // 线程,所以下面的函数,输出的就是当前线程的创建时间,而不是主线程的创建时间
    27. GetThreadCreateTime(Thread);
    28. return 0;
    29. }
    30. int main()
    31. {
    32. // 获取当前线程的伪句柄,计算当前线程的创建时间。线程的伪句柄始终是 -2,进程是 -1
    33. HANDLE MainThread = GetCurrentThread();
    34. // 在主线程中首先打印主线程的创建时间
    35. GetThreadCreateTime(MainThread);
    36. // 如果想要其它线程计算出主线程的创建时间,绝对不能用伪句柄,转换方式如下
    37. HANDLE TrueHandle{};
    38. DuplicateHandle(
    39. GetCurrentProcess(), // 要转换的句柄在哪里
    40. MainThread, // 要转换的句柄是谁
    41. GetCurrentProcess(), // 将句柄拷贝到哪个进程的句柄表
    42. &TrueHandle, // 转换后的句柄保存到哪里
    43. 0, FALSE, DUPLICATE_SAME_ACCESS);
    44. // 等待两秒钟,创建一个新的线程,将主线程的句柄传入,计算线程的创建时间
    45. Sleep(2000);
    46. HANDLE Thread = CreateThread(NULL, 0, WorkerThread, (LPVOID)TrueHandle, 0, NULL);
    47. // 为了确保线程执行完毕,应该等待线程
    48. WaitForSingleObject(Thread, INFINITE);
    49. return 0;
    50. }