问题
I have this code:
private static void Start(String path) {
var process = Process.Start(new ProcessStartInfo(path) {
WindowStyle = ProcessWindowStyle.Maximized,
UseShellExecute = true,
});
ThreadPool.QueueUserWorkItem(Tick, process);
}
private static void Tick(Object obj) {
var process = (Process) obj;
while (true) {
Debug.WriteLine($"HWND: {process.MainWindowHandle}");
Thread.Sleep(TimeSpan.FromMilliseconds(10));
}
}
This starts a process and then displays the MainWindowHandle
property every 10ms. On .NET Framework (I tested 4.5 and 4.8) this displays 0 initially but once the window is fully rendered displays the actual window handle.
The exact same code on .NET Core (tested on 2.0, 2.2, 3.0 and 3.1, 1.0 does not have the necessary API) behaves differently. It either immediately knows the handle and displays the numeric value, or it does not and no amount of waiting will change that, it will keep displaying 0. This is timing related, if I insert a sleep of a few milliseconds into the line before the while loop it always works, without a sleep it almost always does not, except for the rare case when it executes fast enough.
I thought that using process.Refresh()
was meant to help with this case, but it does not seem to have an effect here. I tried adding it to the loop before the debug line without success.
I know the API changed slightly with .NET Core (such as UseShellExecute
having a different default value, which is why I provided it explicitly in my example, just to exclude it as a possible source of the discrepancy), but I do not know if that affected this particular use case as well.
Is this known, and if so, intended? Am I missing something with regards to the usage? And more to the point of the title, how can I reliably get the MainWindowHandle
of a spawned console window? Without having to use an explicit wait, if possible, since I do not know how long it will take the spawned process to start up.
来源:https://stackoverflow.com/questions/59425174/get-mainwindowhandle-of-spawned-process-in-net-core