Giving managed control handles to unmanaged code - Access Violation - c#

So I have this SDK provided by a third party which is used for viewing streaming video from a remote source. The remote source runs a server provided by the third party that captures and stores video, and I can connect to that server and get video via the SDK. I am referencing the SDK via COM, and basic nongraphical operations like connecting to the server, selecting a video feed etc are all working just fine.
The problem is that the main (only) method for actually showing video to the user using this SDK is to pass an hWnd (as an int) into a method that will then asynchronously paint the video onto the client area of that window. "Window" here, to my knowledge, has the meaning of a GUI window, which in .NET terms would be any WinForms control with a window handle. In my case, I'm using PictureBox controls (one per feed the user wishes to see).
The problem is that I apparently cannot just drop a managed PictureBox control's handle into this SDK method, because when I do so I receive an AccessViolationException from the unmanaged thread. I'm working off of an example program written in VB 6 (which works on my computer against a test server) which does the same thing with a VB PictureBox, and that works just fine, but apparently whatever the SDK is trying to do to our nice safe .NET sandbox objects is not flying with the CLR.
Help? I wish I could give more information or a code sample, but I can't provide anything sanitized enough that it would work in the general case and I can't divulge the SDK being used. I think that what I need is simply to tell .NET that my referenced code should be trusted to do what it wants with the window, OR to somehow move the window to an less-managed memory space outside my program's comfy sandbox.
EDIT: OK, a little progress has been made. I am now verifying that the handle for the control has been created using IsHandleCreated, before giving the handle to the method. However, as Hans Passant said, an IntPtr is not an int. So, how do I fit this square peg in the round hole? I have tried both the ToInt32() function and an explicit cast to (int). Neither works, even when compiling my library for 32-bit architecture. Do I go back to the third party and say their SDK is a POS for not letting me pass a pointer?

This should work fine. A Control.Handle for a windows forms control is just a standard HWND from the Windows API. Many DirectX samples use this exact technique.
That being said, make sure this isn't passed into the native code until after the control is created. If you pass the handle during a form's constructor (prior to Load), for example, the Handle will be invalid at that point.

Related

How to capture screenshot from full screen 3D games in C# [duplicate]

Suppose I have an OpenGL game running full screen (Left 4 Dead 2). I'd like to programmatically get a screen grab of it and then write it to a video file.
I've tried GDI, D3D, and OpenGL methods (eg glReadPixels) and either receive a blank screen or flickering in the capture stream.
Any ideas?
For what it's worth, a canonical example of something similar to what I'm trying to achieve is Fraps.
There are a few approaches to this problem. Most of them are icky, and it totally depends on what kind of graphics API you want to target, and which functions the target application uses.
Most DirectX, GDI+ and OpenGL applications are double or tripple-buffered, so they all call:
void SwapBuffers(HDC hdc)
at some point. They also generate WM_PAINT messages in their message queue whenever the window should be drawn. This gives you two options.
You can install a global hook or thread-local hook into the target process and capture WM_PAINT messages. This allows you to copy the contents from the device context just before the painting happens. The process can be found by enumerating all the processes on the system and look for a known window name, or a known module handle.
You can inject code into the target process's local copy of SwapBuffers. On Linux this would be easy to do via the LD_PRELOAD environmental variable, or by calling ld-linux.so.2 explicitly, but there is no equivalient on Windows. Luckily there is a framework from Microsoft Research which can do this for you called Detours. You can find this here: link.
The demoscene group Farbrausch made a demo-capturing tool named kkapture which makes use of the Detours library. Their tool targets applications that require no user input however, so they basically run the demos at a fixed framerate by hooking into all the possible time functions, like timeGetTime(), GetTickCount() and QueryPerformanceCounter(). It's totally rad. A presentation written by ryg (I think?) regarding kkapture's internals can be found here. I think that's of interest to you.
For more information about Windows hooks, see here and here.
EDIT:
This idea intrigued me, so I used Detours to hook into OpenGL applications and mess with the graphics. Here is Quake 2 with green fog added:
Some more information about how Detours works, since I've used it first hand now:
Detours works on two levels. The actual hooking only works in the same process space as the target process. So Detours has a function for injecting a DLL into a process and force its DLLMain to run too, as well as functions that are supposed to be used in that DLL. When DLLMain is run, the DLL should call DetourAttach() to specify the functions to hook, as well as the "detour" function, which is the code you want to override with.
So it basically works like this:
You have a launcher application who's only task is to call DetourCreateProcessWithDll(). It works the same way as CreateProcessW, only with a few extra parameters. This injects a DLL into a process and calls its DllMain().
You implement a DLL that calls the Detour functions and sets up trampoline functions. That means calling DetourTransactionBegin(), DetourUpdateThread(), DetourAttach() followed by DetourTransactionEnd().
Use the launcher to inject the DLL you implemented into a process.
There are some caveats though. When DllMain is run, libraries that are imported later with LoadLibrary() aren't visible yet. So you can't necessarily set up everything during the DLL attachment event. A workaround is to keep track of all the functions that are overridden so far, and try to initialize the others inside these functions that you can already call. This way you will discover new functions as soon as LoadLibrary have mapped them into the memory space of the process. I'm not quite sure how well this would work for wglGetProcAddress though. (Perhaps someone else here has ideas regarding this?)
Some LoadLibrary() calls seem to fail. I tested with Quake 2, and DirectSound and the waveOut API failed to initalize for some reason. I'm still investigating this.
I found a sourceforge'd project called taksi:
http://taksi.sourceforge.net/
Taksi does not provide audio capture, though.
I've written screen grabbers in the past (DirectX7-9 era). I found good old DirectDraw worked remarkably well and would reliably grab bits of hardware-accelerated/video screen content which other methods (D3D, GDI, OpenGL) seemed to leave blank or scrambled. It was very fast too.

Hook for API function GetSystemMetrics

Please help me create hook for AP.I function GetSystemMetrics.
I want that when some app(for example calc.exe) call GetSystemMetrics they receive my value(for example 500x500) and other apps get correct screen size.
And if somebody can tell me how can I do this use C# and .net CF 2.0 I'll be very happy.
Thanks and hope for you help.
I don't think it's possible to do in C#/.NET without writing any native code. However, the good news is that there is a wonderful library called madCodeHook which is really easy to use. Take a look at http://madshi.net/
You can't do that, even in native code (at least not without ugly, bad-idea, vtable/kernel memory hacks that may or may not continue to work across versions of the OS). GetSystemMetrics calls down to the OS to get information about the platform. There's no way, short of recompiling the OS and changing those values, that you can "override" thse values and get the OS to report other numbers (unless, of course, the OS was already built in such a way that those numbers came from somewhere your app can modify - like the registry).
EDIT
Based on your comments, your actual problem is that you're trying to create some form of "taskbar" type application and you'd like other apps outside of your control to not overlay your taskbar when they maximize. This is exactly how the exisiting Explorer taskbar works, so my suggestion is to go look in the default shell source code and see how it is accomplished there.
The end result is likely going to be that you will either clone the existing shell code and modify the existing taskbar to meet your needs, or you'll create an entirely new shell application that has the behavior you want, but you almost certainly are going to have to replace the shell, and that can only be done with native code.

How to find and populate Flash fields of a third party source

In a nutshell, I am looking to see if I can use some kind of reflection to inject values into a running Flash app - not via a communication link, but directly into the app.
Basically, I was asked to find out if it was possible to fill in a third party flash object with values from our program.
I have played around with Sothink SWF decompiler, but did not find anything immediately useful for our needs...but maybe I missed something.
Just a note, I tagged this with C# and C++ because we have low level libraries written in C++, but our main app is C#. So, we are able to use either of these languages to do this if it is indeed possible.
UPDATE
This is for a natural language application. So, the users will want to talk and see the data populated.
It appears that this is not possible without an exposed API that would need to be built custom to each flash development team. Here is a very good reference of how this would need to be done
Basically, there is an IShockwaveFlash* object that can be used to communicate back and forth with the flash interface. However, the flash program must expose this via the flash.external.* package, and then use ExternalInterface methods.
Otherwise, flash is set up as a black box.

Create a WPF "control" that is run in an external process

I have a WPF app which contains a number of child controls.
One of these controls hosts a third party library which underneath the covers runs some native code which throws access violations and crashes the application. Unfortunately removing the library is not an option.
What I'd like to do is spin up a new windows process, host the third party library inside that, and somehow communicate with it. Much in the same way that Google Chrome and IE8 handle browser plugins.
The issue is that the third party library needs to draw to the screen, so I have to somehow have the equivalent of an HTML iframe inside my WPF app's main window.
I'm not sure how to get started on this, it's proving difficult to google for thus far. Any advice is greatly appreciated.
This is a tough one, but fortunately for you there is a little work being done in this space lately.
Have you heard of the System.Addin namespace in .NET 3.5? It could probably help in this case. It allows for controls to be loaded in a separate AppDomain, but be displayed in the same UI. I'd imagine you'd have to do a little bit of work to get everything communicating properly (never done this before), but it's possible.
Have a look at this early post from the Add-in team: http://blogs.msdn.com/clraddins/archive/2007/08/06/appdomain-isolated-wpf-add-ins-jesse-kaplan.aspx
Seems like they keep their samples and helper code on codeplex: http://clraddins.codeplex.com/
I'm very interested in this, so if you get this working, let us know how this went for you!
Coming in way late. If you still need this, have you seen this project: https://learn.microsoft.com/en-us/archive/blogs/changov/hosting-wpf-ui-cross-thread-and-cross-process
I'm running multiple plugins in multiple external processes in my LOB app. My framework grew out of the project above.
Probably not the easiest of tasks. Have you considered hosting your 3rd party stuff in a separate App-Domain? That way you will also get a good level of isolation while saving you the hassle of another project. Does it have to be refreshed constantly or could you refresh at predefined points in your application? Maybe some scheme where you basically do a screenshot of the 3rd party output and show it as image in your original app would then be possible...

Take screenshot of any external application using C#

We have a C# (WPF) application in which we want to take a screenshot of an arbitrary application launched by us (i.e. so we have a reference to the Process we started).
The application may be minimized or behind other windows but we still only want the image of the individual application, not overlapping pixels.
I know the typical P/Invoke solutions using BitBlt or PrintWindow work most of the time, but those fail (I only get black/transparent pixels) when dealing with an DirectX or OpenGL application that draws directly to the graphics device. I have found this article on taking a screenshot of a Direct3D app from C#, so I think I have that case covered.
So my question is this:
How would I do this for an OpenGL application?
What is the easiest way to determine the appropriate method to use (PW/DX/GL)?
Is there a single universal way of doing this?
For #2, am I relegated to inspecting the modules loaded by the executable and seeing if an DirectX or OpenGL DLL/Assembly is loaded?
This only has to run on Windows XP (not cross-platform and not going to Vista/7 anytime soon if ever for this application).
Answer to 1: In OpenGL, you can call glReadBuffer and glReadPixels to get the screen bitmap. However, this is slow (so you don't call it repeatedly every frame) and you might also have problems when th GL window is overlapped by another application / window. The correct way to do this is to "render to texture" (google it) by using a pbuffer.
Idea for 2: If you have the handle to window, you might be able to get the pixelformatdescriptor structure it has and check it. Never tried it though.
For 3: By the way, I don't think there is a single universal way of doing this without any problems..

Categories