✅ Get window handle when it's created
In my WPF app, I want to embed the window from a
Process
(a Unity player application).
I'm extending HwndHost
to host it in a control.
I create a Process with the executable, and start it.
The Unity player obviously takes a bit to load and the window is not created immediately (not even after calling Process.WaitForInputIdle
).
Is there some way of getting the player window handle immediately when it is created?
I tried
- Using Process.MainWindowHandle
, but that value is not set until it's created, so I'd have to block the thread waiting for it.
- Using EnumChildWindows
, may be a bit more reliable, but has the same issue as above.
Ideally I want to start the player process and when it creates the main window immediately embed it, without it flashing on the screen or showing in the task bar.5 Replies
the only way you're getting that level of granularity with inter-process comminication is with APIs that the process itself provides, or with OS-level APIs
what you'd need is some kinda API to intercept and redirect the OS CreateWindow call, or an API to monitor or interecept OS event messages being sent to the process
maybe this lines up with what you're trying to do?
Stack Overflow
How can I make a child process window to appear modal in my process?
I have an application that calls some other utility application to set some settings for a particular device. That utility application is called using ShellExecuteEx.
So as not to confuse the user...
alright, thanks for the info!
It seems that embedding a separate window is quite difficult to do right.
I'm going to try another option that unity gives, by directly calling the player dll in my application.
Idk if that makes it possible to embed correctly but we'll see
Their documentation shows this dll call
extern "C" UNITY_API int UnityMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd);
How do I translate that to C#?
I have this atm:
but it creates an exception
Unhandled Exception: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
Found it, I thought the player was x86 but it was x64
Oh wait this calls the full application ;-;
You have any other ideas on how to embed nicely?
I solved this by using a while
loop until the process.MainWindowHandle
becomes available. To not block the main thread I used an async function that accepted a delegate, and then created a task that, when finished, called the delegate which in turn did all the logic to correctly insert it into my WPF app
This feels 'hacky' but it is what it is
Any other suggestions are welcomeI'm not QUITE sure what you're saying about the mechanics, but yeah, that's pretty much the only option you've got, poll until you find the window
Allright, fair enough, thanks!