2010-07-02 2 views
5

Я тестировал следующий образец кода и как-то всякий раз, когда я пытался его запустить, у меня будет ошибка, показанная ниже. Тем не менее, процесс calc.exe был выполнен успешно, так как возможно, что дескриптор должен быть нулевым или нулевым? Надеюсь, вы понимаете, что я пытаюсь понять. Благодаря! Образец кода от http://www.mathpirate.net/log/tag/system-windows-automation/Автоматизация пользовательского интерфейса Windows

Необработанное исключение типа «System.ArgumentException» произошло в UIAutomationClient.dll Дополнительная информация: HWND не может быть IntPtr.Zero или нулевым.

//Launches the Windows Calculator and gets the Main Window's Handle. 
Process calculatorProcess = Process.Start("calc.exe"); 
calculatorProcess.WaitForInputIdle(); 
IntPtr calculatorWindowHandle = calculatorProcess.MainWindowHandle; 

//Here I use a window handle to get an AutomationElement for a specific window. 
AutomationElement calculatorElement = AutomationElement.FromHandle(calculatorWindowHandle); 

if(calculatorElement == null) 
{ 
    throw new Exception("Uh-oh, couldn't find the calculator..."); 
} 

//Walks some of the more interesting properties on the AutomationElement. 
Console.WriteLine("--------Element"); 
Console.WriteLine("AutomationId: {0}", calculatorElement.Current.AutomationId); 
Console.WriteLine("Name: {0}", calculatorElement.Current.Name); 
Console.WriteLine("ClassName: {0}", calculatorElement.Current.ClassName); 
Console.WriteLine("ControlType: {0}", calculatorElement.Current.ControlType.ProgrammaticName); 
Console.WriteLine("IsEnabled: {0}", calculatorElement.Current.IsEnabled); 
Console.WriteLine("IsOffscreen: {0}", calculatorElement.Current.IsOffscreen); 
Console.WriteLine("ProcessId: {0}", calculatorElement.Current.ProcessId); 

//Commented out because it requires another library reference. However, it's useful to see that this exists. 
//Console.WriteLine("BoundingRectangle: {0}", calculatorElement.Current.BoundingRectangle); 

Console.WriteLine("Supported Patterns:"); 
foreach (AutomationPattern supportedPattern in calculatorElement.GetSupportedPatterns()) 
{ 
    Console.WriteLine("\t{0}", supportedPattern.ProgrammaticName); 
} 

ответ

2

Вы недоразумение WaitForInputIdle (Что это чудовищно плохое имя для того, что в настоящее время делает эту функцию). Вы запрашиваете адрес главного окна до того, как главное окно уже создано. В результате вы заканчиваете передачу недопустимого дескриптора окна другим вашим функциям.

EDIT: Я бы настоятельно рекомендовал использовать библиотеку автоматизации пользовательского интерфейса, такую ​​как white, если вы собираетесь серьезно работать с ней.

+0

Если вы используете Белый, имейте в виду, что у него есть несколько проблем; Я нашел те, которые очень значимы в моем текущем проекте. Вы можете увидеть список проблем с White: http://white.codeplex.com/workitem/list/basic –

+0

Btw, рекомендуется ли использовать автоматизацию пользовательского интерфейса для целей мониторинга? У меня есть стороннее приложение, в котором значения, которые я хочу отслеживать, и на основе значений, я хотел бы выполнить некоторые действия, то есть действия пользовательского интерфейса, нажатие кнопки, изменение значений текстового поля и т. Д. Что касается значений мониторинга, я должен индивидуально контролировать каждый элемент управления? Спасибо! – user303907

Смежные вопросы