You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将通过NtQueryInformationThread获取线程名的C代码改写为C++实现

线程名查询函数C++实现方案

原实现核心逻辑为调用NtQueryInformationThread获取ThreadNameInformation信息,改写为C版本时可利用RAII特性优化内存管理,也可适配C标准字符串类型,以下是两种常用实现:

版本1:兼容原有PH_STRING类型接口

该版本保留和原C函数完全一致的调用方式,仅内部用C++特性优化内存安全,避免手动释放内存导致的泄漏风险:

#include <ntstatus.h>
#include <windows.h>
#include <memory>
// 需引入ProcessHacker相关头文件获取PH_STRING、PhAllocate/PhFree等定义
NTSTATUS PhGetThreadName(
    _In_ HANDLE ThreadHandle,
    _Out_ PPH_STRING *ThreadName
)
{
    NTSTATUS status;
    ULONG bufferSize = 0x100;
    ULONG returnLength = 0;

    // 智能指针自动管理分配的内存,即使函数中途退出也会自动释放
    auto bufferDeleter = [](PTHREAD_NAME_INFORMATION ptr) { PhFree(ptr); };
    std::unique_ptr<THREAD_NAME_INFORMATION, decltype(bufferDeleter)> buffer(
        static_cast<PTHREAD_NAME_INFORMATION>(PhAllocate(bufferSize)), 
        bufferDeleter
    );

    status = NtQueryInformationThread(
        ThreadHandle,
        ThreadNameInformation,
        buffer.get(),
        bufferSize,
        &returnLength
    );

    if (status == STATUS_BUFFER_OVERFLOW)
    {
        // 重置缓冲区,分配符合长度要求的新内存
        buffer.reset();
        bufferSize = returnLength;
        buffer.reset(static_cast<PTHREAD_NAME_INFORMATION>(PhAllocate(bufferSize)));

        status = NtQueryInformationThread(
            ThreadHandle,
            ThreadNameInformation,
            buffer.get(),
            bufferSize,
            &returnLength
        );
    }

    if (NT_SUCCESS(status))
    {
        *ThreadName = PhCreateStringFromUnicodeString(&buffer->ThreadName);
    }

    return status;
}

版本2:C++原生风格实现(返回标准字符串)

如果不需要依赖ProcessHacker的自定义字符串结构,可以直接返回C++标准std::wstring,调用更便捷,无需额外管理字符串内存:

#include <ntstatus.h>
#include <windows.h>
#include <memory>
#include <string>

// 函数返回调用状态,线程名通过输出参数std::wstring返回
NTSTATUS GetThreadName(
    _In_ HANDLE ThreadHandle,
    _Out_ std::wstring& threadName
)
{
    NTSTATUS status;
    ULONG bufferSize = 0x100;
    ULONG returnLength = 0;

    // 用系统API分配内存,不依赖第三方库
    auto bufferDeleter = [](PTHREAD_NAME_INFORMATION ptr) { VirtualFree(ptr, 0, MEM_RELEASE); };
    std::unique_ptr<THREAD_NAME_INFORMATION, decltype(bufferDeleter)> buffer(
        static_cast<PTHREAD_NAME_INFORMATION>(VirtualAlloc(NULL, bufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)),
        bufferDeleter
    );

    status = NtQueryInformationThread(
        ThreadHandle,
        ThreadNameInformation,
        buffer.get(),
        bufferSize,
        &returnLength
    );

    if (status == STATUS_BUFFER_OVERFLOW)
    {
        buffer.reset();
        bufferSize = returnLength;
        buffer.reset(static_cast<PTHREAD_NAME_INFORMATION>(VirtualAlloc(NULL, bufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)));

        status = NtQueryInformationThread(
            ThreadHandle,
            ThreadNameInformation,
            buffer.get(),
            bufferSize,
            &returnLength
        );
    }

    if (NT_SUCCESS(status))
    {
        threadName.assign(buffer->ThreadName.Buffer, buffer->ThreadName.Length / sizeof(WCHAR));
    }
    else
    {
        threadName.clear();
    }

    return status;
}

注意事项

  • 调用NtQueryInformationThread需要进程持有对应线程的THREAD_QUERY_INFORMATION权限
  • THREAD_NAME_INFORMATION结构定义可从WDK头文件获取,也可根据官方规范自行声明
  • 若通过线程ID获取线程名,需要先调用OpenThread拿到线程句柄再传入上述函数

内容的提问来源于stack exchange,提问作者Ahmed Mahmoud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 11:15:03