У меня небольшая проблема. Я хотел бы сделать снимок экрана из Genymotion. Поскольку это не так просто и требует OpenGL Hooking, у меня есть DLL, которая вводится через Easyhook.Снимок экрана с подключенным приложением OpenGL
Теперь DLL перехватывает метод wglSwapBuffers() для обработки буфера, снимает скриншот, а затем возвращает буфер обратно в genymotion. Проблема в том, что он сбрасывает приложение (Kernelbase.dll) и/или mscorlib, как только он пытается использовать любые методы OpenGL.
Удаление этих и просто печать текста при вызове SwapBuffers_Hooked работает хорошо.
Вот длл, который вводится в процесс
public class Main : EasyHook.IEntryPoint
{
GlMon.GlMonInterface Interface;
Stack<String> Queue = new Stack<String>();
public LocalHook CreateBufferHook = null;
Bitmap bitmap = null;
public Main(
RemoteHooking.IContext InContext,
String InChannelName)
{
// connect to host...
Interface = RemoteHooking.IpcConnectClient<GlMon.GlMonInterface>(InChannelName);
Interface.Ping();
}
public void Run(
RemoteHooking.IContext InContext,
String InChannelName)
{
// install hook...
try
{
CreateBufferHook = LocalHook.Create(LocalHook.GetProcAddress("opengl32.dll", "wglSwapBuffers"), new DwglSwapBuffers(SwapBuffers_Hooked), this);
CreateBufferHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
}
catch (Exception ExtInfo)
{
Interface.ReportException(ExtInfo);
return;
}
Interface.IsInstalled(RemoteHooking.GetCurrentProcessId());
RemoteHooking.WakeUpProcess();
try
{
while (true)
{
Thread.Sleep(500);
// transmit newly monitored file accesses...
if (this.bitmap != null)
{
Interface.onSwapBuffer(RemoteHooking.GetCurrentProcessId(), "bitmap received. size=" + bitmap.Size);
this.bitmap = null;
}
else
{
Interface.onSwapBuffer(RemoteHooking.GetCurrentProcessId(), "ping..");
Interface.Ping();
}
}
}
catch
{
// Ping() will raise an exception if host is unreachable
}
// wait for host process termination...
}
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
delegate IntPtr DwglSwapBuffers(IntPtr hdc);
[DllImport("opengl32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
static extern IntPtr wglSwapBuffers(IntPtr hdc);
// this is where we are intercepting all file accesses!
static IntPtr SwapBuffers_Hooked(IntPtr hdc)
{
Main This = (Main)HookRuntimeInfo.Callback;
try
{
/** apitrace dump is
*
11288 wglSwapBuffers(hdc = 0xb0013e0a) = TRUE
11289 glFlush()
11290 wglMakeCurrent(hdc = 0xf601374b, hglrc = 0x10004) = TRUE
11291 glDisable(cap = GL_SCISSOR_TEST)
11292 glClear(mask = GL_COLOR_BUFFER_BIT)
11293 glEnable(cap = GL_SCISSOR_TEST)
11294 glDisable(cap = GL_BLEND)
11295 glBindTexture(target = GL_TEXTURE_2D, texture = 20)
11296 glPushClientAttrib(mask = GL_CLIENT_VERTEX_ARRAY_BIT)
11297 glPushAttrib(mask = GL_TRANSFORM_BIT)
11298 glMatrixMode(mode = GL_PROJECTION)
11299 glPushMatrix()
11300 glLoadIdentity()
11301 glGetIntegerv(pname = GL_VIEWPORT, params = {0, 0, 860, 720})
11302 glOrtho(left = 0, right = 860, bottom = 0, top = 720, zNear = 0, zFar = -1)
11303 glMatrixMode(mode = GL_TEXTURE)
11304 glPushMatrix()
11305 glLoadIdentity()
11306 glMatrixMode(mode = GL_MODELVIEW)
11307 glPushMatrix() * **/
Bitmap bitmap = new Bitmap(860, 720);
Rectangle bounds = new Rectangle(0, 0, 860, 720);
BitmapData bmpData = bitmap.LockBits(bounds, ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
wgl.glReadBuffer((uint)wgl.DrawBufferMode.GL_FRONT_AND_BACK);
wgl.glReadPixels(0, 0, bounds.Width, bounds.Height, (uint)wgl.PixelFormat.GL_RGB, (uint)wgl.DataType.GL_UNSIGNED_BYTE, bmpData.Scan0);
bitmap.UnlockBits(bmpData);
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
int i = 0;
while (File.Exists("images/test_" + i + ".png"))
{
i++;
}
bitmap.Save("images/test_" + i + ".png");
return wgl.SwapBuffers(hdc);
}
catch
{
}
// call original API...
return wglSwapBuffers(hdc);
}
Погрешность Крэш
Problemereignisname: APPCRASH
Anwendungsname: player.exe
Anwendungsversion: 0.0.0.0
Anwendungszeitstempel: 54edc8da
Fehlermodulname: KERNELBASE.dll
Fehlermodulversion: 6.3.9600.17415
Другой Исключение отображается отладчик является System.FileNotFoundexception, но я не могу понять, какой файл не найден.
Обновление: я обновил код. Этот код работает в большинстве случаев, и изображения хранятся. Во всяком случае, у них есть раздражающие цвета. Похоже, что некоторые цвета отсутствуют и/или имеют меньший красный цвет. Что может вызвать эту проблему? если я выберу другой PixelFormat, он снова сработает. То же самое с GL_RGB. RGBA, похоже, падает. Если я увеличиваю DataType, он также сработает. Любая идея, почему цвета переполнены?
спасибо. Я хочу обновить код. Я до сих пор работаю, но цвета все еще повреждены. Любая идея почему? –
Растровые изображения используют формат BGR, а не RGB.также убедитесь, что все правила выравнивания выполнены – derhass