C# OpenGL/DirectX挂钩-类似于FRAPS

C# OpenGL/DirectX挂钩-类似于FRAPS,c#,c++,winapi,opengl,directx,C#,C++,Winapi,Opengl,Directx,是否有可能检测到哪些应用程序正在使用类似于FRAPS的OpenGL或DirectX?(可能使用某种形式的挂钩)?我可能不需要实际绘制窗口,我只需要知道哪些进程正在进行某种形式的3D渲染 (编辑:) 如果您不熟悉,FRAPS是一个程序,可用于在3D应用程序上绘制“每秒帧数”计数器。FRAPS会自动查找所有正在运行的3D应用程序,而无需您指定进程名称 绘制到外部游戏的“每秒帧数”计数器示例: 最简单的方法可能是检查OpenGL和DirectX核心库的存在,也可能是在中添加驱动程序OGL DLL(例如

是否有可能检测到哪些应用程序正在使用类似于FRAPS的OpenGL或DirectX?(可能使用某种形式的挂钩)?我可能不需要实际绘制窗口,我只需要知道哪些进程正在进行某种形式的3D渲染

(编辑:) 如果您不熟悉,FRAPS是一个程序,可用于在3D应用程序上绘制“每秒帧数”计数器。FRAPS会自动查找所有正在运行的3D应用程序,而无需您指定进程名称

绘制到外部游戏的“每秒帧数”计数器示例:

最简单的方法可能是检查OpenGL和DirectX核心库的存在,也可能是在中添加驱动程序OGL DLL(例如nvogl)的一个好主意,这可以通过&,使用p/invoke来完成,这将至少为您提供一组可能使用OGL或DX的启动进程

当然,有些应用程序同时加载这两个API并只使用一个,或者只有条件地使用一个 GFXAPI之一(尽管后者只出现在专用工具和类似工具中),对于这一点,IMO,最好的检查方法是执行某种形式的注入 或者像调试器一样附加到进程,然后为DX挂起
Present
,或为OGL挂起
wglSwapBuffers

通过枚举GDI句柄并查找DXGI或OGL渲染上下文,您可能会不使用钩子,这有多可行,我不知道

你应该看看这篇链接文章


第二个链接有一些概念代码,应该做实际的钩子部分。它还涉及到一些更为详细的问题,比如我想复制和粘贴到这个答案中的方式和原因。

据我所知,FRAPS使用了一种相对暴力的方法来决定在哪里开店。该进程从SetWindowsHookEx开始,请求操作系统将FRAPS hook DLL加载到它可以加载的每个正在运行的进程[以及未来的进程]中。DLL的神奇之处在于使用GetModuleHandleA运行一组程序测试,以观察它所连接的进程是否加载了任何OpenGL/DirectX模块。如果所有调用都返回NULL,则钩子将尝试从进程中移除自身

另一方面,如果进程已加载它们,它只需通过移除保护并注入JMP钩子,从该库中钩住相应的渲染函数。wglSwapBuffers通常是OpenGL中唯一相关的。当进程调用此函数时,它最终调用FRAPS模块,然后FRAPS将后缓冲区捕获到其队列中,用于编码到AVI,并呈现其少量指示。然后,它处理wglSwapBuffers的原始请求,并将执行返回给程序


至于在C#中查询。。。复习简易书(http://easyhook.codeplex.com/)看看它是否对你有用。我个人没有使用此API的经验

我的猜测是,您正在寻找的函数隐藏在Microsoft的Windows API中。我会在那里寻找解决方案。你可以看看。它是FRAPS的开源替代品。最重要的是,您可以查看源代码并找到所需内容。请注意,并非所有使用DirectX/Direct3d的应用程序都在进行3D渲染。我们使用D3D渲染H.264视频。我认为这对dx有帮助@Deanna+1感谢Deanna的警告,这是另外一个需要注意的问题。来自MSDN:“如果此函数是从运行在WOW64上的32位应用程序调用的,它只能枚举32位进程的模块。如果进程是64位进程,则此函数失败,最后一个错误代码是error_PARTIAL_COPY(299)。”这不是问题,但我需要的东西,这两个32/64位工作。如果进程是64位的呢?这是否意味着,如果我将应用程序编译为64位,它应该使用32/64?或者,如果你是32位的,你就不能枚举64位的应用程序?@David:有一个32位和64位的变体可用(
EnumProcessModulesEx
),你需要一个64位的应用程序才能同时获得32位和64位的进程(参见备注),而且你仍然需要32位操作系统的32位构建。