Что нового

Запуск из папки случайного фотофайла

Grell

Новичок
Сообщения
127
Репутация
0
Версия AutoIt: 3.3.14.0

Описание:
Добрый день, специалисты по autoit
Подскажите решение.

Есть скрипт выхватывающий из папки C:\1\ (где лежит десяток видеофайлов) случайный видеофайл, открывает его программой по умолчанию и располагает в определенных координатах монитора - с определенными размерами окна.
Хотел заставить этот скрипт - открывать фото-файлы jpg вместо видеофайлов.

Подскажите - как подправить код, чтобы он открывал файлы jpg (из папки C:\1\ ) - и также размещал окно программы с файлом - с теми же координатами и параметрами окна ?

Примечания:
Код:
#include <File.au3>
#include <WinAPIReg.au3>
#include <WinAPIProc.au3>

Local $sDir = 'C:\1' ; Папка
Local $sFileType = '*.avi;*.mpg' ; Расширения файлов для поиска
Local $aPos[4] = [100, 200, 200, 150] ; Координаты окна плеера
Local $hWnd, $aFiles, $sRunProgram, $iPID, $hTimer, $aProgWindows, $sRunFile

$aFiles = _FileListToArrayRec($sDir, $sFileType, $FLTA_FILES, $FLTAR_NORECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
If @error Then Exit -1

$sRunFile = $aFiles[0] > 1 ? $aFiles[Random(1, $aFiles[0], 1)] : $aFiles[1]

$sRunProgram = _WinAPI_AssocQueryString(StringRight($sRunFile, 4), $ASSOCSTR_EXECUTABLE) ; Редактор по умолчанию, ассоциированный в ОС с данным типом
If @error Or StringRight($sRunProgram, 4) = '.dll' Then Exit -2

$iPID = Run('"' & $sRunProgram & '" "' & $sRunFile & '"')
If Not $iPID Then Exit -3

$hTimer = TimerInit()
Do ; Некоторые плееры доооолго запускаются
    $aProgWindows = _WinAPI_EnumProcessWindows($iPID)
    If Not @error Then
        For $i = 1 To $aProgWindows[0][0]
            If WinActive($aProgWindows[$i][0]) Then
                $hWnd = $aProgWindows[$i][0]
                $aProgWindows = ''
                ExitLoop 2
            EndIf
        Next
        Sleep(200)
    EndIf
Until TimerDiff($hTimer) > 5000 ; Ждем ~ 5 секунд
If Not $hWnd Then Exit -4

WinMove($hWnd, '', Default, Default, $aPos[2], $aPos[3])
If Not WinMove($hWnd, '', $aPos[0], $aPos[1]) Then Exit -5
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Подскажите - как подправить код, чтобы он открывал файлы jpg (из папки C:\1\ )
У Вас же переменная есть , вот и правьте её:
Код:
Local $sFileType = '*.avi;*.mpg;*.jpg' ; Расширения файлов для поиска
 
Автор
G

Grell

Новичок
Сообщения
127
Репутация
0
ra4o , поменял строчку кода. Скрипт не работает.
Ошибку не выдает, но и файлы JPG-BMP не запускает,

Код:
#include <File.au3>
#include <WinAPIReg.au3>
#include <WinAPIProc.au3>

Local $sDir = 'C:\1' ; Папка
Local $sFileType = '*.jpg;*.bmp' ; Расширения файлов для поиска
Local $aPos[4] = [100, 200, 200, 150] ; Координаты окна 
Local $hWnd, $aFiles, $sRunProgram, $iPID, $hTimer, $aProgWindows, $sRunFile

$aFiles = _FileListToArrayRec($sDir, $sFileType, $FLTA_FILES, $FLTAR_NORECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
If @error Then Exit -1

$sRunFile = $aFiles[0] > 1 ? $aFiles[Random(1, $aFiles[0], 1)] : $aFiles[1]

$sRunProgram = _WinAPI_AssocQueryString(StringRight($sRunFile, 4), $ASSOCSTR_EXECUTABLE) ; Редактор по умолчанию, ассоциированный в ОС с данным типом
If @error Or StringRight($sRunProgram, 4) = '.dll' Then Exit -2

$iPID = Run('"' & $sRunProgram & '" "' & $sRunFile & '"')
If Not $iPID Then Exit -3

$hTimer = TimerInit()
Do ; Некоторые плееры доооолго запускаются
    $aProgWindows = _WinAPI_EnumProcessWindows($iPID)
    If Not @error Then
        For $i = 1 To $aProgWindows[0][0]
            If WinActive($aProgWindows[$i][0]) Then
                $hWnd = $aProgWindows[$i][0]
                $aProgWindows = ''
                ExitLoop 2
            EndIf
        Next
        Sleep(200)
    EndIf
Until TimerDiff($hTimer) > 5000 ; Ждем ~ 5 секунд
If Not $hWnd Then Exit -4

WinMove($hWnd, '', Default, Default, $aPos[2], $aPos[3])
If Not WinMove($hWnd, '', $aPos[0], $aPos[1]) Then Exit -5
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Файлы находит ? Проверьте - допишите:
Код:
$aFiles = _FileListToArrayRec($sDir, $sFileType, $FLTA_FILES, $FLTAR_NORECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
#include <array.au3>
If IsArray($aFiles) Then
	_ArrayDisplay($aFiles)
Else
	MsgBox(0,'Ошибка !','Файлы не найдены !')
EndIf

OffTopic:
Заключайте код в теги "autoit" "/autoit" (только в квадратных скобках)
 
Автор
G

Grell

Новичок
Сообщения
127
Репутация
0
ra4o , добавил эту строчку кода.
Теперь происходит следующее.
Появляется окошко, с таблицей - где приведены полные адреса файлов jpg.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Вот и хорошо, значит функция
Код:
_FileListToArrayRec()
отрабатывает нормально! Нужно смотреть дальше в чём проблема
Исправьте теги на текстах скриптов в предыдущих постах, а то текст плохо читаемый.
Проблема в том , что в функцию должно передаваться разрешение с точкой. Попробуйте заменить строку на эту:
Код:
$sRunProgram = _WinAPI_AssocQueryString('.'&_WinAPI_PathFindExtension($sRunFile), $ASSOCSTR_EXECUTABLE)
 
Автор
G

Grell

Новичок
Сообщения
127
Репутация
0
ra4o , заменил эту строчку кода.
Скрипт по прежнему не открывает файлы jpg.

Код:
#include <File.au3>
#include <WinAPIReg.au3>
#include <WinAPIProc.au3>

Local $sDir = 'C:\1' ; Папка
Local $sFileType = '*.jpg;*.bmp' ; Расширения файлов для поиска
Local $aPos[4] = [100, 200, 200, 150] ; Координаты окна
Local $hWnd, $aFiles, $sRunProgram, $iPID, $hTimer, $aProgWindows, $sRunFile

$aFiles = _FileListToArrayRec($sDir, $sFileType, $FLTA_FILES, $FLTAR_NORECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
If @error Then Exit -1

$sRunFile = $aFiles[0] > 1 ? $aFiles[Random(1, $aFiles[0], 1)] : $aFiles[1]

$sRunProgram = _WinAPI_AssocQueryString('.'&_WinAPI_PathFindExtension($sRunFile), $ASSOCSTR_EXECUTABLE) ; Редактор по умолчанию, ассоциированный в ОС с данным типом
If @error Or StringRight($sRunProgram, 4) = '.dll' Then Exit -2

$iPID = Run('"' & $sRunProgram & '" "' & $sRunFile & '"')
If Not $iPID Then Exit -3

$hTimer = TimerInit()
Do ; Некоторые плееры доооолго запускаются
    $aProgWindows = _WinAPI_EnumProcessWindows($iPID)
    If Not @error Then
        For $i = 1 To $aProgWindows[0][0]
            If WinActive($aProgWindows[$i][0]) Then
                $hWnd = $aProgWindows[$i][0]
                $aProgWindows = ''
                ExitLoop 2
            EndIf
        Next
        Sleep(200)
    EndIf
Until TimerDiff($hTimer) > 5000 ; Ждем ~ 5 секунд
If Not $hWnd Then Exit -4

WinMove($hWnd, '', Default, Default, $aPos[2], $aPos[3])
If Not WinMove($hWnd, '', $aPos[0], $aPos[1]) Then Exit -5
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
С Вашим кодом и у меня не открывало, так как расширение файла передавалось в функцию без точки. Этот вариант, как по мне более надёжен, проверял у себя - работает. С какой ошибкой прекращает работу скрипт ?
 
Автор
G

Grell

Новичок
Сообщения
127
Репутация
0
ra4o , код ошибку не выдает - просто не открывает файлы.
(при запуске скрипта - ничего не происходит)


Код:
#include <File.au3>
#include <WinAPIReg.au3>
#include <WinAPIProc.au3>

Local $sDir = 'C:\1' ; Папка
Local $sFileType = '*.jpg' ; Расширения файлов для поиска
Local $aPos[4] = [100, 200, 200, 150] ; Координаты окна
Local $hWnd, $aFiles, $sRunProgram, $iPID, $hTimer, $aProgWindows, $sRunFile

$aFiles = _FileListToArrayRec($sDir, $sFileType, $FLTA_FILES, $FLTAR_NORECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
If @error Then Exit -1

$sRunFile = $aFiles[0] > 1 ? $aFiles[Random(1, $aFiles[0], 1)] : $aFiles[1]

$sRunProgram = _WinAPI_AssocQueryString('.'&_WinAPI_PathFindExtension($sRunFile), $ASSOCSTR_EXECUTABLE) ; Редактор по умолчанию, ассоциированный в ОС с данным типом
If @error Or StringRight($sRunProgram, 4) = '.dll' Then Exit -2

$iPID = Run('"' & $sRunProgram & '" "' & $sRunFile & '"')
If Not $iPID Then Exit -3

$hTimer = TimerInit()
Do ; Некоторые плееры доооолго запускаются
    $aProgWindows = _WinAPI_EnumProcessWindows($iPID)
    If Not @error Then
        For $i = 1 To $aProgWindows[0][0]
            If WinActive($aProgWindows[$i][0]) Then
                $hWnd = $aProgWindows[$i][0]
                $aProgWindows = ''
                ExitLoop 2
            EndIf
        Next
        Sleep(200)
    EndIf
Until TimerDiff($hTimer) > 5000 ; Ждем ~ 5 секунд
If Not $hWnd Then Exit -4

WinMove($hWnd, '', Default, Default, $aPos[2], $aPos[3])
If Not WinMove($hWnd, '', $aPos[0], $aPos[1]) Then Exit -5

Назначил другую программу по-умолчанию - все равно не помогает.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Смотрите в консоли , когда скрипт завершает работу - пишет красным шрифтом код, с которым он выходит ( то что записано после exit в коде) таким образом можно понять где он вышел, плюс поставьте проверки на массив файлов, на переменные , что-бы посмотреть , что у Вас происходит. Ещё раз повторюсь, что Ваш код с теми исправлениями, что я дал у меня работает и с той информацией , что Вы даёте мне остаётся только гадать, что у Вас происходит.
Проверил скрипт с Вашего поста выше (подставил свой путь к папке с фотографиями) - отрабатывает нормально.
 
Автор
G

Grell

Новичок
Сообщения
127
Репутация
0
ra4o , после завершения работы скрипта - в консоли написано следующее:

>"C:\Program Files (x86)2\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "C:\111222333\567567.au3"
>Exit code: 4294967294 Time: 0.101
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Впишите проверку массива и переменных
 
Автор
G

Grell

Новичок
Сообщения
127
Репутация
0
ra4o , не подскажете как вписать проверку массива и переменных ?
Я не очень хорошо разбираюсь в автоит.
Посмотрел в интернете по этому вопросу - ничего не нашел.
Как сделать проверку массива и переменных?
 
A

Alofa

Гость
Grell, работать таким образом с картинками и проще и сложней одновременно.
Если вы будите использовать мой скрипт как шаблон, то самое проблематичное это вычислить PID процесса программы, которая ассоциирована в Windows с данным типом файла. Если это стороннее ПО, то никаких проблем (точнее возможные проблемы другого характера), а вот если это виндовый просмтрщик по умолчанию, то тут начинаются танцы с бубном.
Оказывается функция _WinAPI_AssocQueryString(), которая и возвращает путь до исполняемого файла, в разных ОС возвращает разные значения. Оно вроде бы и понятно, но как вы примените Run() к .DLL (это в Win7)?
ShellExecute(), в данной ситуации тоже бессильно.

Но зато можно сделать вот так:
Код:
#include <File.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Global Const $STM_SETIMAGE = 0x0172

Local $sDir = 'C:\1' ; Папка
Local $sFileType = '*.bmp;*.jpg' ; Расширения файлов для поиска
Local $aPos[4] = [100, 20, 500, 500] ; Координаты окна плеера
Local $hGUI, $aFiles, $sRunFile, $hBitmap, $hBitmap_Scaled, $hGDIBmp, $iScale_Width, $iScale_Height, $iScale

$aFiles = _FileListToArrayRec($sDir, $sFileType, $FLTA_FILES, $FLTAR_NORECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
If @error Then Exit 2
$sRunFile = $aFiles[0] > 1 ? $aFiles[Random(1, $aFiles[0], 1)] : $aFiles[1]

$hGUI = GUICreate('', $aPos[2], $aPos[3], $aPos[0], $aPos[1]);, $WS_POPUP, $WS_EX_CONTROLPARENT)
GUISetBkColor(0)
_GDIPlus_Startup()
$hBitmap = _GDIPlus_BitmapCreateFromFile($sRunFile)
$iScale_Width = $aPos[2] / _GDIPlus_ImageGetWidth($hBitmap)
$iScale_Height = $aPos[3] / _GDIPlus_ImageGetHeight($hBitmap)
$iScale = ($iScale_Width > $iScale_Height) ? $iScale_Height : $iScale_Width

$hBitmap_Scaled = _GDIPlus_ImageScale($hBitmap, $iScale, $iScale)
$hGDIBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Scaled)

$iPic = GUICtrlCreatePic('', ($aPos[2] - _GDIPlus_ImageGetWidth($hBitmap_Scaled))/2, ($aPos[3] - _GDIPlus_ImageGetHeight($hBitmap_Scaled))/2)
GUICtrlSendMsg($iPic, $STM_SETIMAGE, 0, $hGDIBmp)
GUISetState()

_WinAPI_DeleteObject($hGDIBmp)
_GDIPlus_BitmapDispose($hBitmap_Scaled)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Alofa
ShellExecute(), в данной ситуации тоже бессильно.
Ну, почему же? Зачем нам процессы, если есть окна. Активные окна ;)
Код:
$hActive = WinGetHandle("")
ShellExecute("1.jpg")
Do
  $hWnd = WinGetHandle("")
Until $hWnd <> $hActive
WinMove($hWnd, "", 100, 100, 800, 600)
 
A

Alofa

Гость
InnI сказал(а):
... Зачем нам процессы, если есть окна...
Когда я осознал то, о чем писал выше именно так и сделал. Ну а затем переключил ОС на Win10 и получил другое окно. Оно конечно можно сделать проверку версии ОС и подстроиться под любую, но зачем?

Ах да, на счет сторонних просмотрщиков. Сам пользую FastStone Image Viewer на весь экран. Так вот скрипт-то конечно масштабирует окно, но это не надолго - при очередной перерисовке Viewer самовосстанавливается.
В общем тут тоже геморрой, который нужно героически побеждать.
 
Автор
G

Grell

Новичок
Сообщения
127
Репутация
0
Alofa , все работает.
Огромное спасибо.


Добавлено:
Сообщение автоматически объединено:

InnI , ваш скрипт тоже работает, но выхватывает только один файл 1.jpg - вместо любого случайного файла jpg из папки C:\1\
 
A

Alofa

Гость
Grell, вот скрипт InnI, как вам нужно:
Код:
#include <File.au3>

Local $sDir = 'C:\1' ; Папка
Local $sFileType = '*.bmp;*.jpg' ; Расширения файлов для поиска
Local $aPos[4] = [100, 20, 300, 300] ; Координаты окна плеера
Local $hGUI, $aFiles, $sRunFile, $hActive, $hWnd

$aFiles = _FileListToArrayRec($sDir, $sFileType, $FLTA_FILES, $FLTAR_NORECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
If @error Then Exit 2
$sRunFile = $aFiles[0] > 1 ? $aFiles[Random(1, $aFiles[0], 1)] : $aFiles[1]

$hActive = WinGetHandle("")
ShellExecute($sRunFile)
Do
  $hWnd = WinGetHandle("")
Until $hWnd <> $hActive
WinSetState($hWnd, '', @SW_RESTORE)
WinMove($hWnd, "", $aPos[0], $aPos[1], $aPos[2], $aPos[3])

Но учтите, если во время выполнения ShellExecute() вы активируете какое-нибудь иное окно, то масштабироваться будет именно оно.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Grell
скрипт тоже работает, но выхватывает только один файл 1.jpg
Я знаю. Это был просто пример.

Alofa
если во время выполнения ShellExecute() вы активируете какое-нибудь иное окно
Хотел бы я посмотреть на того, кто успеет это сделать с помощью мыши и клавиатуры.
 
A

Alofa

Гость
OffTopic:
InnI сказал(а):
... Хотел бы я посмотреть на того, кто успеет это сделать с помощью мыши и клавиатуры.
Я успел. Сам удивился. Вероятность мала, но она есть.
Кроме того после ShellExecute() притормозить может антивирус, UAC, или сама запускаемая программа, или...
 
Верх