Что нового

[Автоматизация] Получение текста окна из MsgBox другой программы с помощью WinGetText

drd0s

Новичок
Сообщения
19
Репутация
2
Версия AutoIt: 3.3.8.1
Описание: Получение текста окна из MsgBox другой программы с помощью WinGetText – не работает.
Всем привет.
Столкнулся с проблемой – есть программа, которая кричит при каждом действии, что её период скоро закончится и нужно убивать в автомате это окно.
Проблем с закрытием окна нет, проблема в том что у этой программы частенько выскакивают окна с элементами управления – кнопками (да\нет\отмена) и у всех у них заголовок – Предупреждение, также как и у того который нужно закрывать.
Пытался по всякому получить текст MsgBox’a но вместо этого функция WinGetText возвращает мне текст кнопки – ОК.

Как пытался получить текст:
Код:
$title='Предупреждение'
$iPID = Run('C:\ProfSegment\Profstroy3\ProfStr3.exe -t');Запуск_программы
If ProcessExists($iPID) THEN
While 1
	WinWait($title,'',3)
	$hWnd=WinGetHandle($title)
	$text=WinGetText($hWnd)
	MsgBox(0,'',$text)
WEnd

Endif

082f28f068bb9aafd118f7bfab5a8ee8.jpg

Подскажите, пожалуйста, способ как получить текст для дальнейшего сравнения строки.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Предупреждение За нарушение правил форума (пункт В.11):
Любые отрывки AutoIt кода необходимо заключать в тег [autoit]
autoit.gif
(подробнее), а обычный код соответственно в тег [code]
code.gif
(подробнее). Также большие выдержки текста помещайте под тег [spoiler]
spoiler.gif
(подробнее), там где это поддерживается естественно. Как в случае с названием темы, также короткое и эргономичное сообщение привлекает больше внимания, и шансы на получение конкретного ответа увеличиваются.


С уважением, ваш Глобальный модератор.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Код:
$title='Калькулятор'
$iPID = Run('calc.exe');Запуск_программы
While ProcessExists($iPID)
	If WinExists($title) Then
		$sText = WinGetText($title)
		MsgBox(0,0,$sText)
	EndIf
	Sleep(1000)
WEnd
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
drd0s

Тут нужно типа такого:
Код:
#include <WinAPIEx.au3>

$okno = 'Предупреждение' ; заголовок окон с сообщениями

While 1
	$var = WinList($okno) ; получаем список окон
	For $n = 1 to $var[0][0]
		$aData = _WinAPI_EnumChildWindows($var[$n][1])
		For $i = 1 To $aData[0][0]
			$text = ControlGetText($var[$n][1], '', $aData[$i][0])
			
			If StringInStr($text, 'Завершается период действия') Then ; подстрока из надписи
				MsgBox(0, '', 'Есть окно с надписью ' & $text)

				;список действий- закрытие окна и т.д.
				;WinClose ($var[$n][1], '')
			Endif

		Next
	Next
	sleep(3000)
Wend


WinAPIEx.au3 брать здесь http://autoit-script.ru/index.php/topic,47.0.html
Положить все файлы либо рядом со скриптом, либо в папку Include в папке Autoit
 
Автор
drd0s

drd0s

Новичок
Сообщения
19
Репутация
2
Увы, ни один из вариантов не работает :(
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Вполне возможно, что эти окна вроде окошек 1С, как в этой теме
http://autoit-script.ru/index.php?topic=4926.0
т.е. надписи из них по-простому не читаются

Поэтому можно, как и там, сначала просканировать надпись этого окна Control Viewer
http://autoit-script.ru/index.php/topic,4579.0.html
или
InqSoft Window Scanner
http://kickme.to/inqsoft

Но так как вроде нужно это окно просто закрыть, можно попробовать по размеру(оно должно быть гораздо шире других из-за надписи):
Код:
WinClose('[W:164; H:188]', '') ; указать размеры окна

или
Код:
WinClose('[TITLE:Предупреждение; CLASS:#32770; W:164; H:188]', '')  ; указать заголовок, класс и размеры окна
 
Автор
drd0s

drd0s

Новичок
Сообщения
19
Репутация
2
WSWR, огромное спасибо! Я и не догадался что можно отталкиваться от размеров окна! :beer:
Сделал так:
Код:
$iPID = Run('C:\ProfSegment\Profstroy3\ProfStr3.exe -t')
If ProcessExists($iPID) THEN
while 1
	$title='Предупреждение'
	WinWait($title,'',3)
	WinClose('[H:122; W:501]')
	IF ProcessExists($iPID) = 0 Then
		Exit
	EndIf
WEnd
Else
	MsgBox(0,"Error","Процесс не запущен!")
	Exit
EndIf
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
Вопрос можно ?))))

А зачем указывать в "WinWait" "$title", а закрывать по "координатам" ???

Код:
$title='Предупреждение'

$iPID = Run('C:\ProfSegment\Profstroy3\ProfStr3.exe -t')
ProcessWait($iPID)
While 1
	If ProcessExists($iPID) Then
		WinWait($title, '')
		WinClose($title, '')
	Else
        ExitLoop 1
;~ 		Exit
    EndIf
Sleep(100)
WEnd

MsgBox(0, "END", "Успешно отработанно...")


ЗЫ: чисто теоритически - мы тогда не дождемся "WinWait", а точнее дождемся, но будем на нем сидеть
 
Автор
drd0s

drd0s

Новичок
Сообщения
19
Репутация
2
---Zak---, ну WinWait ждет 3 секунды перед тем как цикл запуститься снова. Если его не будет - то есть предположение дополнительной нагрузки на ЦП или я ошибаюсь :blink:
Только что проверил, кушает на сервере от 17% до 35% ЦП, может конечно обойтись и Sleep, но я не уверен что это есть хорошо.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
2 drd0s
Ты не совсем меня понял...
Код:
WinWait($title,'',3)
    WinClose('[H:122; W:501]')

и
Код:
WinWait($title, '', 3)
        WinClose($title, '')


Ты же ждешь окно с названием "Предупреждение" - почему бы тогда и не закрывать это окно по тому же названию ???

Или допустим не сделать так:
Код:
$title='Завершается период действия договора'

$iPID = Run('C:\ProfSegment\Profstroy3\ProfStr3.exe -t')
ProcessWait($iPID)
While 1
    If ProcessExists($iPID) Then
        WinClose('', $title)
    Else
        ExitLoop 1
;~      Exit
    EndIf
Sleep(100)
WEnd

MsgBox(0, "END", "Успешно отработано...")

Но здесь будет закрывать вообще все окна в которых есть 'Завершается период действия договора'


ЗЫ: на счет Sleep():
http://autoit-script.ru/index.php/topic,5591.0.html
http://autoit-script.ru/index.php/topic,2448.0.html
http://autoit-script.ru/index.php/topic,8561.0.html

Код:
WinWait($title,'',3)

Он не ждет 3 секунды, а это тайм-аут для ожидания окна, т.е. если окно не появится в течении 3 секунд скипт будет дальше выполняться. Т.е. с одной стороны - да - он ждет 3 секунды, но с другой стороны скрипт все равно закроет окно по твоим координатам.

ЗЫЫ: в своем пред примере убрал "3" из "WinWait"
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
---Zak--- [?]
Ты же ждешь окно с названием "Предупреждение" - почему бы тогда и не закрывать это окно по тому же названию
...
А зачем указывать в "WinWait" "$title", а закрывать по "координатам"
Потому что
drd0s [?]
у всех у них заголовок – Предупреждение, также как и у того который нужно закрывать.

---Zak--- [?]
Но здесь будет закрывать вообще все окна в которых есть 'Завершается период действия договора'
Не будет, т.к.
drd0s [?]
Пытался по всякому получить текст MsgBox’a но вместо этого функция WinGetText возвращает мне текст кнопки – ОК.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
2 InnI
1. Намек понял - извиняюсь - не заметил
2. Проверил - да есть такая штука, но тогда не понятно что это за окно...

ЗЫ: а можно как-нибудь узнать "decimal flag" окна ??? Пойду новую тему создам, чтобы не флудить.
 
Верх