Windows 新版本怎么实现截图

1 天前
 xueyuehua

以前写过一个 Python 脚本,用 pywin32 利用窗口句柄实现内存截图,在 win10 上可以正常使用,窗口被遮挡也可以截图,甚至可以在后台操作鼠标。 但是为什么在 win11 上用不了了,用 c# 实现也是不行,是 win11 新内核导致的吗? 有大佬知道什么解决方案吗

958 次点击
所在节点    Python
4 条回复
yqf0215
1 天前
Windows 11 确实对窗口安全性和隐私做了一些增强,这影响了一些基于窗口句柄的操作。以下是几种可能的解决方案:
1 使用 Windows Graphics Capture API:
```
# 需要安装 Windows SDK 和 Python 包
# pip install windows-capture
from windows_capture import WindowsGraphicsCapture

def capture_window(hwnd):
capturer = WindowsGraphicsCapture()
image = capturer.capture_window(hwnd)
return image
```

2 使用提升权限的方式:
```
import win32security
import win32con
import win32api

def enable_privileges():
# 获取需要的权限
priv_flags = (
win32security.TOKEN_ADJUST_PRIVILEGES |
win32security.TOKEN_QUERY
)

# 获取当前进程的 token
h_token = win32security.OpenProcessToken(
win32api.GetCurrentProcess(),
priv_flags
)

# 提升权限
privileges = [
(win32security.LookupPrivilegeValue(
None,
win32security.SE_DEBUG_NAME
),
win32con.SE_PRIVILEGE_ENABLED)
]

# 应用权限
win32security.AdjustTokenPrivileges(
h_token,
0,
privileges
)
```

3 使用 DirectX 捕获方式:
```
// C# 示例
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.DXGI;

public class ScreenCapture
{
private Factory1 factory;
private Adapter1 adapter;
private Device device;
private Output output;
private Output1 output1;

public void Initialize()
{
factory = new Factory1();
adapter = factory.GetAdapter1(0);
device = new Device(adapter);
output = adapter.GetOutput(0);
output1 = output.QueryInterface<Output1>();
}

public Bitmap CaptureScreen()
{
// 实现截图逻辑
// ...
}
}
```

4 使用 SetWinEventHook 监听窗口事件:
```
import win32con
import win32api
import win32gui
import ctypes
from ctypes import wintypes

def win_event_callback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime):
if event == win32con.EVENT_SYSTEM_FOREGROUND:
# 处理窗口事件
pass

def setup_hook():
user32 = ctypes.windll.user32

# 设置事件钩子
WinEventProcType = ctypes.WINFUNCTYPE(
None,
wintypes.HANDLE,
wintypes.DWORD,
wintypes.HWND,
wintypes.LONG,
wintypes.LONG,
wintypes.DWORD,
wintypes.DWORD
)

win_event_proc = WinEventProcType(win_event_callback)

user32.SetWinEventHook(
win32con.EVENT_SYSTEM_FOREGROUND,
win32con.EVENT_SYSTEM_FOREGROUND,
0,
win_event_proc,
0,
0,
win32con.WINEVENT_OUTOFCONTEXT
)
```

5 考虑使用 UI 自动化框架:
```
from comtypes.client import CreateObject

def capture_using_uiautomation():
UIAutomation = CreateObject("UIAutomationCore.CUIAutomation")
element = UIAutomation.GetRootElement()
# 实现截图和自动化操作
```

主要建议:
1 优先使用 Windows Graphics Capture API ,这是微软推荐的新方法
2 如果需要后台操作,考虑使用 UI 自动化框架
3 对于特权操作,确保:
以管理员权限运行
正确处理 UAC
申请必要的系统权限

4 如果是开发生产环境应用,建议:
使用官方支持的 API
实现适当的错误处理
考虑兼容性问题

5 监控系统事件和性能:
使用事件钩子
实现错误日志
处理资源释放

这些方法中,Windows Graphics Capture API 是最推荐的方案,因为它:
是官方支持的新 API
性能更好
兼容性更好
更安全
如果这些方法都不能满足需求,可能需要考虑使用其他技术方案或重新设计应用程序的架构。
xueyuehua
1 天前
@yqf0215 谢谢大佬给了这么多种方案,我试试看
xqzr
1 天前
@Livid #1 AI(?)
yqf0215
1 天前
cursor

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1103314

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX