Pull to refresh

Обрабатываем ошибки и вылеты проприета́рных программ

Reading time 5 min
Views 4.2K
Если вы занимались пакетной обработкой в Adobe Photoshop с помощью инструмента Automate — Batch (пакетная обработка очень большого количества графических файлов с наложением на них фильтров из программы в автоматическом режиме), наверняка сталкивались с такого вида вылетами программы, по не понятным для меня причинам:





Конечно можно ждать появление этих ошибок, которые могут возникнуть через час обработки или через несколько часов, можно заводить будильник, чтобы просыпаться ночью (как робот) и смотреть: «а не вылетел ли Photoshop» с ошибкой? Потом нервно снова запускать обработку, отсортировывая уже обработанные файлы в другую папку.

В кратце вот и проблема! (Аналогично Вы сможете обрабатывать ошибки и от другого программного обеспечения). Решение?






Как возникли эти ошибки?

Я решил обработать видео, с помощью фильтров Photoshop. В VirtualDub импортировал Mov с помощью plugin-ов. Сделал раскадровку File — Export — Image Sequence, заказал имя файла, тип файла, количество цифр, папку. Экспортировал mov в огромное колчество bmp файлов и начал пакетную обработку в Photoshop. Результат обработки потом планировал через VirtualDub экспортировать уже в готовый файл avi, применив еще и фильтр Deshaker, который устранит дрожания камеры. Но тут начались вылеты Photoshop, например при простом сохранении в файл png ошибка «Because the file-format module cannot parse the file» (фотошоп выдает ошибку, о том, что он не может отпарсерить в файл-форматном модуле?)

Будем обрабатывать ошибки Photoshop с помощью скриптового языка AutoIt. Для этого нам потребуется запастись кофе терпением: ожидать появление ошибок, описать реагирование на них, протестировать, собрать готовое решение в виде exe файла с готовыми и автоматизированными действиями компьютера.

Окна об ошибках будем изучать с помощью инструмента AutoIt с названием AutoIt Windows Info. На удивление окна Adobe Photoshop не используют стандартные windows Api окна, но сообщения об ошибках программа видит без проблем:



if WinExists("Adobe Photoshop CS3 Extended","OK") then
WinWait("Adobe Photoshop CS3 Extended","OK")
;ждем окно 30 секунд с ошибкой и кнопкой OK и делаем его активным
sleep(3000)
WinActivate("Adobe Photoshop CS3 Extended","OK")
sleep(3000)
;ControlClick("Adobe Photoshop CS3 Extended","OK","[CLASS:Static; INSTANCE:2]")
;WinClose("Adobe Photoshop CS3 Extended","OK")
sleep(3000)
;msgbox(1,"1","1")
;окно для теста, что все нормально
;если не помогло нажатие на кнопку, просто закроем Adobe Photoshop
ProcessClose("Photoshop.exe")
endif


Аналогично можно закрыть ошибку с текстом Microsoft Visual C++ Runtime Library:

if WinExists("Microsoft Visual C++ Runtime Library","") Then
winwait("Microsoft Visual C++ Runtime Library","")
WinActivate("Microsoft Visual C++ Runtime Library","")
winclose("Microsoft Visual C++ Runtime Library","")
;msgbox(0,"First","1")
EndIf

sleep(10000)

if WinExists("Photoshop.exe - Application Error","OK") Then
winwait("Photoshop.exe - Application Error","OK")
WinActivate("Photoshop.exe - Application Error","OK")
controlclick("Photoshop.exe - Application Error","OK","[CLASS:Button; INSTANCE:1]")
EndIf

sleep(10000)

if WinExists("Photoshop.exe - Application Error","OK") Then
WinActivate("Photoshop.exe - Application Error","OK")
winwait("Photoshop.exe - Application Error","OK")
controlclick("Photoshop.exe - Application Error","OK","[CLASS:Button; INSTANCE:1]")
EndIf

sleep(10000)


Ошибки обрабатываются, программа закрывается. Необходимо запустить ее заново. Горячие клавиши для запуска пакетной обработки AdobePhotoshop в английской версии Alt+f (File) — u (aUtomate) — Alt+a (Action) — чтобы выбрать наш профиль для обработки — будем использовать клавиши стрелка вниз («на клавиатуре» — через скрипт соответственно), либо если не хотите использовать горячие клавиши — с помощью клавиатуры вверх-вверх, enter и т.д…



ShellExecute("C:\Program Files\Adobe\Adobe Photoshop CS3\Photoshop.exe","","C:\Program Files\Adobe\Adobe Photoshop CS3\")
sleep(30000)
;ждем подольше, иначе компьютер вслепую начнет отправлять нажатия клавиши в воздух!
IF WinExists("Adobe Photoshop CS3 Extended","") Then
WinActivate("Adobe Photoshop CS3 Extended","")
Send("!f")
;File
sleep(5000)
Send("u")
;aUtomate
sleep(5000)
Send("b")
;Batch
sleep(5000)
;старый вариант - через меню подъем курсора снизу вверх
;send("{UP}")
;sleep(10000)
;send("{UP}")
;sleep(10000)
;send("{UP}")
;sleep(10000)
;send("{UP}")
;sleep(1000)
;send("{UP}")
;sleep(10000)
;send("{UP}")
;sleep(10000)
;send("{UP}")
;sleep(10000)
;send("{ENTER}")
;sleep(10000)
;send("{ENTER}")
;sleep(10000)
;Set - выбираем - тип настроек профиля для обработки. В моем случае он третий по счету, поэтому нужно _нажать_ 2 раза клавишу на клавиатуре со стрелкой вниз
send("!t")
sleep(10000)
send("{DOWN}")
sleep(10000)
send("{DOWN}")
sleep(10000)
send("{ENTER}")
EndIf


Чему мы уже научили компьютер? Закрывать возникающие ошибки, запускать обработку Photoshop. Но при внимательном рассмотрении, компьютер начинает обработку в этой же папке, и не разбирается в том: обработан файл или еще нет, происходит «вторичная» обработка уже обработанных ранее файлов, а затем он переходит к файлам, которые необходимо обработать. Что же делать?

Будем обработанные файлы сохранять в другой формат, например png (растровый формат хранения графической информации, использующий сжатие без потерь по алгоритму Deflate). По именам сохранных файлов *.png будем удалять исходные наши файлы *.jpeg или *.bmp. Изучив документацию и примеры AutoIt, получился следующий скрипт (ищет файлы *.png — по их названиям стирает исходные файлы *.bmp).:

#include <file.au3>
#include <array.au3>

Dim $szDrive, $szDir, $szFName, $szExt

sleep(10000)

$flagvixod = 0

; Shows the filenames of all files in the current directory.
$search = FileFindFirstFile("*.png")

; Check if the search was successful
If $search = -1 Then
MsgBox(0, "Error", "No files/directories matched the search pattern")
;считаем что все обработано - т.к. нет уже готовых файлов png
Exit
EndIf

While 1
$file = FileFindNextFile($search)
If @error Then ExitLoop

$TestPath = _PathSplit(@ScriptDir & "\" & $file, $szDrive, $szDir, $szFName, $szExt)
;3 = name , 4 = extension
;получим имя файла png и заменим его на bmp и сотрем!
DelMyFile($TestPath[3] & ".bmp")

WEnd

Func DelMyFile($value)
;msgbox (0,"0",$value)
;return $value
If FileExists($value) Then
filedelete($value)
Else
Return $value
endif
EndFunc


Не забудьте дописать в пакетную обработку действие File — Save As… сохранение файла по сохранению png.

Осталось все это собрать в единый файл, «зациклить обработку» на поиск ошибок. Или добавить задание в планировщик задач windows (Scheduled Task), которое будет автоматически раз в несколько минут, проверять искать возникающую ошибку на экране компьютера и за нас принимать решение — закрывать их, закрывать программу, удалять исходные необработанные файлы (по списку сохраненных и уже обработанных), запускать заново Photoshop для обработки. Паузы в скрипте по 10-30 секунд добавлены для надежности, т.к. иногда после возникновения ошибок компьютер не вполне корректно и быстро реагирует на нажатия клавиш.
Tags:
Hubs:
-3
Comments 19
Comments Comments 19

Articles