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

如何为游戏窗口设置SetWindowDisplayAffinity为WDA_NONE以实现画面捕获?

解决SetWindowDisplayAffinity调用时的权限拒绝问题

出现PermissionError: [WinError 5] Access denied通常是因为Python进程权限不足,或者目标游戏窗口存在进程保护机制,以下是可行的解决思路:

  • 以管理员身份运行脚本
    很多游戏默认会以管理员权限启动,如果你的Python脚本权限低于游戏进程,就会被拒绝访问。右键点击你的Python脚本或Python解释器,选择「以管理员身份运行」再尝试执行。

  • 启用调试权限(SeDebugPrivilege)
    对于一些高权限进程,需要获取调试权限才能修改其窗口属性。可以在代码中添加权限提升逻辑,修改后的完整代码如下:

import ctypes
import ctypes.wintypes

# 权限相关定义
SE_DEBUG_NAME = "SeDebugPrivilege"
TOKEN_ADJUST_PRIVILEGES = 0x0020
TOKEN_QUERY = 0x0008
SE_PRIVILEGE_ENABLED = 0x0002

class LUID(ctypes.Structure):
    _fields_ = [
        ("LowPart", ctypes.wintypes.DWORD),
        ("HighPart", ctypes.wintypes.LONG)
    ]

class LUID_AND_ATTRIBUTES(ctypes.Structure):
    _fields_ = [
        ("Luid", LUID),
        ("Attributes", ctypes.wintypes.DWORD)
    ]

class TOKEN_PRIVILEGES(ctypes.Structure):
    _fields_ = [
        ("PrivilegeCount", ctypes.wintypes.DWORD),
        ("Privileges", LUID_AND_ATTRIBUTES * 1)
    ]

def enable_debug_privilege():
    htoken = ctypes.wintypes.HANDLE()
    # 获取当前进程的令牌
    if not ctypes.windll.advapi32.OpenProcessToken(
        ctypes.windll.kernel32.GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
        ctypes.byref(htoken)
    ):
        return False
    
    luid = LUID()
    # 获取SeDebugPrivilege的LUID
    if not ctypes.windll.advapi32.LookupPrivilegeValueW(
        None, SE_DEBUG_NAME, ctypes.byref(luid)
    ):
        ctypes.windll.kernel32.CloseHandle(htoken)
        return False
    
    tp = TOKEN_PRIVILEGES()
    tp.PrivilegeCount = 1
    tp.Privileges[0].Luid = luid
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
    
    # 启用权限
    result = ctypes.windll.advapi32.AdjustTokenPrivileges(
        htoken,
        False,
        ctypes.byref(tp),
        ctypes.sizeof(tp),
        None,
        None
    )
    
    ctypes.windll.kernel32.CloseHandle(htoken)
    return result != 0

# 先启用调试权限
if not enable_debug_privilege():
    print("Failed to enable debug privilege")

WDA_NONE = 0x00000000  # No restrictions on window display

# Load the user32 DLL
user32 = ctypes.WinDLL("user32", use_last_error=True)

# 替换成你的游戏窗口标题
game_window_name = "Your Game Window Title"

# Find the window handle by its title. The first parameter (class name) is None.
hwnd = user32.FindWindowW(None, game_window_name)
if hwnd == 0:
    raise Exception(f"Window with title {game_window_name} not found.")

# Call SetWindowDisplayAffinity to set the window's display affinity.
result = user32.SetWindowDisplayAffinity(hwnd, WDA_NONE)
if result == 0:
    # If the function fails, raise an error with the last error code.
    raise ctypes.WinError(ctypes.get_last_error())

print(f"{result=}")
  • 检查游戏的反作弊/保护机制
    如果游戏带有VAC、Easy Anti-Cheat(EAC)或其他反作弊系统,这类系统会阻止外部进程修改窗口属性,防止被捕获。这种情况下强行修改可能触发反作弊检测,导致账号封禁,不建议尝试。

  • 确认窗口句柄正确性
    有时候FindWindowW可能找到同名的其他窗口,导致修改了错误的进程。可以使用Windows自带的Spy++工具(Visual Studio工具集内)定位正确的游戏窗口句柄,或者结合GetWindowThreadProcessId获取进程ID,验证是否为目标游戏的进程ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:58:12