C# 等待第三方应用程序窗口加载

C# 等待第三方应用程序窗口加载,c#,multithreading,wait,window-load,C#,Multithreading,Wait,Window Load,我正在尝试创建一个C#.NET 2.0脚本,以便在用Java编写的第三方应用程序中自动化工作流 我使用user32.dll函数来与Java应用程序窗口交互 我的问题是Java应用程序窗口完全加载缓慢,通过IntPtr SendMessage(IntPtr hWnd、UInt32 Msg、UInt32 wParam、IntPtr lParam)发送的操作有时会丢失。示例:在加载主窗口期间,如果我尝试打开菜单(此时我在主窗口上实际上有一个句柄),我的消息将丢失,菜单将永远不会打开 我在Stack O

我正在尝试创建一个C#.NET 2.0脚本,以便在用Java编写的第三方应用程序中自动化工作流

我使用user32.dll函数来与Java应用程序窗口交互

我的问题是Java应用程序窗口完全加载缓慢,通过
IntPtr SendMessage(IntPtr hWnd、UInt32 Msg、UInt32 wParam、IntPtr lParam)发送的操作有时会丢失。示例:在加载主窗口期间,如果我尝试打开菜单(此时我在主窗口上实际上有一个句柄),我的消息将丢失,菜单将永远不会打开

我在Stack Overflow上找到了一些答案,告诉我们可以使用
Process.WaitForInputIdle()
方法来实现这一目的,但我发现这只在应用程序是单线程的情况下起作用,而我的Java应用程序不是这样。()

我正在寻找一种工作原理相同但支持多线程或任何其他想法的东西?!:)

按照Mari9的想法,我最终使用了
System.Diagnostic.PerformanceCounter()
来观察第三方应用程序流程活动。然后,它将通信到0,这意味着进程已经完成了它必须做的事情,并且能够执行我发送给它的消息

PerformanceCounter PC = new PerformanceCounter();
PC.CategoryName = "Process";
PC.CounterName = "% Processor Time";
PC.InstanceName = "<process name>";
Console.WriteLine(PC.NextValue().ToString());
PerformanceCounter PC=新的PerformanceCounter();
PC.CategoryName=“过程”;
PC.CounterName=“%处理器时间”;
PC.InstanceName=“”;
Console.WriteLine(PC.NextValue().ToString());

我假设您有一种方法可以检测您想要发送输入的窗口何时显示在屏幕上,但由于窗口忙,立即发送输入不起作用

您可以有一个预定义的/硬编码的等待时间间隔(可能为每个Java窗口定制)-这不是很可靠,但在受控环境中可能工作得很好(例如,如果应用程序仅在您的计算机上使用)

如果加载完成后窗口的外观发生了可靠的变化,您可以捕获窗口的屏幕截图并测试是否存在正确的像素,然后在发送消息之前重复此操作,直到为真

另一个选项是使用Spy++查看加载完成时是否为窗口生成了任何特定消息(例如,可能是带有特定参数的重新绘制),并安装一个钩子来检测这些消息

如果Java应用程序使用本机窗口控件(SWT),则可以尝试检测窗口文本/结构中指示加载完成的更改


如果窗口加载过程是资源密集型的,您也可以监视java应用程序的CPU使用情况,并在发送消息之前等待“峰值”结束。

删除了答案,因为我没有阅读您问题的第二部分:-(我已经使用sleeps来让我的脚本工作。我不喜欢这种解决方案,要么我留有足够的空白,脚本会变慢,要么我没有使用足够的空白,脚本有时会失败。对于消息解决方案,我没有找到指示窗口加载完成的消息。关于你对屏幕截图的想法,你知道吗一个在C#中运行良好的API?我更喜欢通过P/Invoke捕获窗口,因为它捕获的窗口与上面的窗口无关:我必须承认我的函数并不总是有效的。我可能会尝试pinvoke。但我需要一个好的(快速的)图像比较函数。