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

获取全屏进程名时GetModuleBaseNameA返回错误5(ACCESS_DENIED),求低权限方法

问题描述

我尝试获取处于全屏模式运行的进程名称,但打开任意游戏并执行以下代码时,即使以管理员权限运行,GetLastError()仍返回错误5(ACCESS_DENIED)。我推测这是由反作弊机制导致的,但我仅需要获取进程名称,请问是否存在所需权限更低的获取方法?

#include <windows.h>
#include <psapi.h>

HWND hwnd = GetForegroundWindow();
    char name_buffer[256] = "";
    int buffer_size = 256;
    if (!hwnd) {
        strncpy(name_buffer, "No fullscreen app detected", buffer_size - 1);
        name_buffer[buffer_size - 1] = '\0';
        return;
    }   

    RECT window_rect;
    GetWindowRect(hwnd, &window_rect);

    int screen_width = GetSystemMetrics(SM_CXSCREEN);
    int screen_height = GetSystemMetrics(SM_CYSCREEN);

    if((window_rect.right - window_rect.left) >= screen_width && (window_rect.bottom - window_rect.top) >= screen_height){

        DWORD process_id;
        GetWindowThreadProcessId(hwnd, &process_id);
        HANDLE process_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_id);

        if (process_handle) {
            if (GetModuleBaseNameA(process_handle, NULL, name_buffer, buffer_size) == 0) {
                obs_log(LOG_ERROR, "Failed to get module base name: %lu", GetLastError());
                strncpy(name_buffer, "Unknown", buffer_size - 1);
                name_buffer[buffer_size - 1] = '\0';
            }
        CloseHandle(process_handle);
        } else {
            strncpy(name_buffer, "OpenProcess failed", buffer_size - 1);
            name_buffer[buffer_size - 1] = '\0';
        }
    }
解决方案

以下几种方法可在更低权限下获取进程名称,避开反作弊的权限拦截:

  • 直接获取窗口标题
    多数全屏游戏的窗口标题包含进程名称(或可映射到进程名),无需打开进程句柄。调用GetWindowTextA即可,该API仅需窗口访问权限,通常不会被反作弊拦截。

    修改示例:

    if((window_rect.right - window_rect.left) >= screen_width && (window_rect.bottom - window_rect.top) >= screen_height){
        // 用窗口标题替代进程名
        if (!GetWindowTextA(hwnd, name_buffer, buffer_size)) {
            strncpy(name_buffer, "Unknown Window", buffer_size - 1);
            name_buffer[buffer_size - 1] = '\0';
        }
    }
    
  • 使用宽松权限打开进程并查询路径
    若需获取进程可执行文件名,可尝试用PROCESS_QUERY_LIMITED_INFORMATION权限打开进程——该权限比PROCESS_QUERY_INFORMATION更宽松,多数场景下不会被反作弊拒绝。随后调用QueryFullProcessImageNameA获取路径,再从路径中提取文件名作为进程名。

    修改示例:

    if((window_rect.right - window_rect.left) >= screen_width && (window_rect.bottom - window_rect.top) >= screen_height){
    
        DWORD process_id;
        GetWindowThreadProcessId(hwnd, &process_id);
        // 使用PROCESS_QUERY_LIMITED_INFORMATION权限
        HANDLE process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id);
    
        if (process_handle) {
            char path_buffer[MAX_PATH] = "";
            DWORD path_len = MAX_PATH;
            if (QueryFullProcessImageNameA(process_handle, 0, path_buffer, &path_len)) {
                // 从路径中提取文件名
                char* filename = strrchr(path_buffer, '\\');
                if (filename) {
                    strncpy(name_buffer, filename + 1, buffer_size - 1);
                } else {
                    strncpy(name_buffer, path_buffer, buffer_size - 1);
                }
                name_buffer[buffer_size - 1] = '\0';
            } else {
                strncpy(name_buffer, "Unknown", buffer_size - 1);
                name_buffer[buffer_size - 1] = '\0';
            }
            CloseHandle(process_handle);
        } else {
            strncpy(name_buffer, "OpenProcess failed", buffer_size - 1);
            name_buffer[buffer_size - 1] = '\0';
        }
    }
    
  • 通过WMI查询进程信息
    借助Windows的WMI服务,查询Win32_Process类中对应PID的进程名称。这种方式无需直接打开进程句柄,通过系统服务获取信息,权限要求更低,但调用逻辑相对复杂,适合对性能要求不高的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 22:24:52