1 (изменено: g0ss, 2018-10-26 15:06:51)

Тема: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Здравствуйте. Изучаю COM IE. Столкнулся с проблемой - скрипт застывает при открытии окна "загрузка файла на сайт" (после закрытия этого окна продолжает работу). Скрипт я запускаю на виртуальной машине VmWare - Win 10 от имени администратора.


#NoEnv
#singleInstance, Force
#MaxThreads, 100
#MaxThreadsPerHotkey, 2
#Persistent
SetBatchLines, -1
DetectHiddenWindows, On
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
CoordMode, Tooltip, Screen
SetTitleMatchMode, 2
SetKeyDelay, 30,50
SetMouseDelay 10
SendMode Event
#InstallKeybdHook
#InstallMouseHook
#UseHook, On

loop,
{
pwb := ComObjCreate("InternetExplorer.Application")
pwb.Visible := True

;Делает браузер на весь экран
IfWinExist, Internet Explorer
	{
	WinActivate
	WinMaximize
	}

pwb.Navigate("xxx.com")
While pwb.Busy or pwb.ReadyState != 4
	Sleep, 100

;Заполнение форму случайным значением из текстового файла.
Random, ProLine, 1, 50
FileReadLine, Pro, C:\Users\PC\Dropbox\Pro.txt, %ProLine%

pro_input := pwb.document.getElementById("pro_headline")
pro_input.value := Pro
Sleep, 100

;Нажимает на кнопку Browse file (выбрать файл для загрузки на сайт)
pwb.document.getElementById("browse_file").click()
Sleep, 100

;Тут скрипт застывает. Продолжает работу, если закрыть окно. Окно по умолчанию активно.
IfWinExist, Choose File to Upload
{
	WinMaximize
}

;Дабл клик на первый файл.
Sleep 1500
Click 240, 153
Sleep 100
Click 240, 153
Sleep 3000

;Нажимает кнопку
While ( value <> "Done" ) 
	value := pwb.document.getElementsByTagName( "input")[ A_Index - 1].innerText, index := A_Index - 1 
pwb.document.getElementsByTagName( "input")[ index].Click()
While pwb.Busy or pwb.ReadyState != 4
	Sleep, 100
}

;Горячие клавиши.
Pause::Pause
Esc::Exit

Горячие клавиши так же не работают. Вот так выглядит окно загрузки файла: https://imgur.com/a/DDEp85Z

Подскажите, что я делаю не так. Спасибо!

2

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

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

3

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Я делал:


Run, winwait.ahk

;Далее код winwait.ahk
WinWait, Choose File to Upload,
IfWinNotActive, Choose File to Upload, , WinActivate, Choose File to Upload,
WinWaitActive, Choose File to Upload,
Click 240, 150
ExitApp

Думал, что есть более изящное решение, но все ровно спасибо. Может быть знаете, почему не работают горячие клавиши?

4

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

g0ss пишет:

Думал, что есть более изящное решение

Скорее всего, можно решить вопрос с помощью таймера.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Сомневаюсь, так как IE останавливает поток скрипта, возможно из-за защиты от загрузки файлов без согласия пользователя.
Вариант использовать AHK_H который поддерживает многопоточность.

6

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Существует такой таймер на WinApi: SetTimer
Он не замораживается.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Да, действительно не замораживается.
Но вряд ли код с использованием этого таймера выйдет изящнее.

8

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Тут уж от исполнения зависит.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9 (изменено: Malcev, 2018-10-28 22:29:43)

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Таймер сработает только если после появления окна для загрузки файлов кликнуть вручную правой кнопкой мыши на иконку запущенного скрипта.
Так что похоже не вариант.

#persistent
DllCall("SetTimer", Ptr, A_ScriptHwnd, Ptr, id := 1, UInt, 50, Ptr, RegisterCallback("MyTimer", "F"))

oIE := ComObjCreate("InternetExplorer.Application") 
oIE.visible := True, oIEHWND := oIE.HWND 
WinMaximize ahk_id %oIEHWND%  
oIE.navigate("https://www.youtube.com/upload")
While oIE.readyState != 4 || oIE.document.readyState != "complete" || oIE.busy
   Sleep, 10
oIE.document.querySelector("input[type=""file""]").click()



MyTimer()
{
   Global n
   n++
   if winexist("ahk_class #32770 ahk_exe IEXPLORE.EXE")
   {
      tooltip work
      DllCall("KillTimer", Ptr, A_ScriptHwnd, Ptr, id := 1)
      msgbox
   }
   tooltip % n
}

10

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

У меня срабатывает без клика:

https://i.imgur.com/sXtsSON.png

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

А, нет, я перед этим вручную на кнопку загрузки кликнул, потому что через IE сначала авторизоваться пришлось. Если скрипт кликает, тогда не срабатывает.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12 (изменено: teadrinker, 2018-10-29 23:42:40)

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Вот так работает:

oIE := ComObjCreate("InternetExplorer.Application")
OnExit( Func("IeQuit").Bind(oIE) )
oIE.visible := true
oIE.navigate("https://www.youtube.com/upload")
While oIE.readyState != 4 || oIE.document.readyState != "complete" || oIE.busy
   Sleep, 10

UnFreeze(200, Func("MyFunc"))
oIE.document.querySelector("input[type=""file""]").click()

MyFunc()  {
   Loop  {
      if WinExist("ahk_class #32770 ahk_exe IEXPLORE.EXE")  {
         MsgBox, do stuff here
         break
      }
      Sleep, 100
   }
}

IeQuit(oIE)  {
   if WinExist("ahk_class #32770 ahk_exe IEXPLORE.EXE")
      ControlClick, Button2
   try oIE.Quit()
}

UnFreeze(timeOut, userFunc)  {
   static SYNCHRONIZE := 0x100000, hGui, oInfo := {}
        , _ := OnMessage( msg := DllCall("RegisterWindowMessage", Str, "WM_INFO"), Func("WM_INFO").Bind(oInfo) )
   if !hGui
      Gui, New, +hwndhGui
   hProc := DllCall("OpenProcess", UInt, SYNCHRONIZE, UInt, 0, UInt, DllCall("GetCurrentProcessId"), Ptr)
   pPtr := GetProcAddr(hProc, hGui, msg, timeOut)
   oInfo.func := userFunc, oInfo.hProc := hProc
   DllCall("CreateThread", Ptr, 0, Ptr, 0, Ptr, pPtr, Ptr, 0, UInt, 0, Ptr, 0)
}

WM_INFO(oInfo)
{
   DllCall("CloseHandle", Ptr, oInfo.hProc)
   oInfo.func.Call()
}

GetProcAddr(Handle, hWnd, Msg, Timeout=-1)
{  ; на основе http://forum.script-coding.com/viewtopic.php?pid=56073#p56073
   static MEM_COMMIT := 0x1000, PAGE_EXECUTE_READWRITE := 0x40
   ptr := DllCall("VirtualAlloc", Ptr, 0, Ptr, A_PtrSize = 4 ? 49 : 85, UInt, MEM_COMMIT, UInt, PAGE_EXECUTE_READWRITE, Ptr)
   , hModule := DllCall("GetModuleHandle", Str, "kernel32.dll", Ptr)
   , pWaitForSingleObject := DllCall("GetProcAddress", Ptr, hModule, AStr, "WaitForSingleObject", Ptr)
   , hModule := DllCall("GetModuleHandle", Str, "user32.dll", Ptr)
   , pSendMessageW := DllCall("GetProcAddress", Ptr, hModule, AStr, "SendMessageW", Ptr)
   , NumPut(pWaitForSingleObject, ptr*1)
   , NumPut(pSendMessageW, ptr + A_PtrSize)
   if (A_PtrSize = 4)  {
      NumPut(0x68, ptr + 8, "UChar")
      , NumPut(Timeout, ptr + 9, "UInt"), NumPut(0x68, ptr + 13, "UChar")
      , NumPut(Handle, ptr + 14), NumPut(0x15FF, ptr + 18, "UShort")
      , NumPut(ptr, ptr + 20), NumPut(0x6850, ptr + 24, "UShort")
      , NumPut(Handle, ptr + 26), NumPut(0x68, ptr + 30, "UChar")
      , NumPut(Msg, ptr + 31, "UInt"), NumPut(0x68, ptr + 35, "UChar")
      , NumPut(hWnd, ptr + 36), NumPut(0x15FF, ptr + 40, "UShort")
      , NumPut(ptr+4, ptr + 42), NumPut(0xC2, ptr + 46, "UChar"), NumPut(4, ptr + 47, "UShort")
   }
   else  {
      NumPut(0x53, ptr + 16, "UChar")
      , NumPut(0x20EC8348, ptr + 17, "UInt"), NumPut(0xBACB8948, ptr + 21, "UInt")
      , NumPut(Timeout, ptr + 25, "UInt"), NumPut(0xB948, ptr + 29, "UShort")
      , NumPut(Handle, ptr + 31), NumPut(0x15FF, ptr + 39, "UShort")
      , NumPut(-45, ptr + 41, "UInt"), NumPut(0xB849, ptr + 45, "UShort")
      , NumPut(Handle, ptr + 47), NumPut(0xBA, ptr + 55, "UChar")
      , NumPut(Msg, ptr + 56, "UInt"), NumPut(0xB948, ptr + 60, "UShort")
      , NumPut(hWnd, ptr + 62), NumPut(0xC18941, ptr + 70, "UInt")
      , NumPut(0x15FF, ptr + 73, "UShort"), NumPut(-71, ptr + 75, "UInt")
      , NumPut(0x20C48348, ptr + 79, "UInt"), NumPut(0xC35B, ptr + 83, "UShort")
   }
   return ptr + A_PtrSize*2
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

Запостил твоё решение на оффоруме.
https://autohotkey.com/boards/viewtopic … 53#p247253

14

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

OFF: блин, что они с сайтом сделали. Раньше можно было выбрать цветовую тему, добавляя к ссылке определённый код, например style=17, но сейчас это не работает, страница не форматируется.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

teadrinker, не знаешь насколько верно будет использовать данный код в цикле?

loop
{
   UnFreeze(200, Func("MyFunc"))
   oIE.document.querySelector("input[type=""file""]").click()
   msgbox unfreeze
}

Есть ли какие подводные камни?

oIE := ComObjCreate("InternetExplorer.Application")
OnExit( Func("IeQuit").Bind(oIE) )
oIE.visible := true
oIE.navigate("https://www.youtube.com/upload")
While oIE.readyState != 4 || oIE.document.readyState != "complete" || oIE.busy
   Sleep, 10

loop
{
   UnFreeze(200, Func("MyFunc"))
   oIE.document.querySelector("input[type=""file""]").click()
   msgbox unfreeze
}

MyFunc()  {
   Loop  {
      if WinExist("ahk_class #32770 ahk_exe IEXPLORE.EXE")  {
         MsgBox, do stuff here
         break
      }
      Sleep, 100
   }
}

IeQuit(oIE)  {
   if WinExist("ahk_class #32770 ahk_exe IEXPLORE.EXE")
      ControlClick, Button2
   try oIE.Quit()
}

UnFreeze(timeOut, userFunc)  {
   static SYNCHRONIZE := 0x100000, hGui, oInfo := {}
        , _ := OnMessage( msg := DllCall("RegisterWindowMessage", Str, "WM_INFO"), Func("WM_INFO").Bind(oInfo) )
   if !hGui
      Gui, New, +hwndhGui
   hProc := DllCall("OpenProcess", UInt, SYNCHRONIZE, UInt, 0, UInt, DllCall("GetCurrentProcessId"), Ptr)
   pPtr := GetProcAddr(hProc, hGui, msg, timeOut)
   oInfo.func := userFunc, oInfo.hProc := hProc
   DllCall("CreateThread", Ptr, 0, Ptr, 0, Ptr, pPtr, Ptr, 0, UInt, 0, Ptr, 0)
}

WM_INFO(oInfo)
{
   DllCall("CloseHandle", Ptr, oInfo.hProc)
   oInfo.func.Call()
}

GetProcAddr(Handle, hWnd, Msg, Timeout=-1)
{  ; на основе http://forum.script-coding.com/viewtopic.php?pid=56073#p56073
   static MEM_COMMIT := 0x1000, PAGE_EXECUTE_READWRITE := 0x40
   ptr := DllCall("VirtualAlloc", Ptr, 0, Ptr, A_PtrSize = 4 ? 49 : 85, UInt, MEM_COMMIT, UInt, PAGE_EXECUTE_READWRITE, Ptr)
   , hModule := DllCall("GetModuleHandle", Str, "kernel32.dll", Ptr)
   , pWaitForSingleObject := DllCall("GetProcAddress", Ptr, hModule, AStr, "WaitForSingleObject", Ptr)
   , hModule := DllCall("GetModuleHandle", Str, "user32.dll", Ptr)
   , pSendMessageW := DllCall("GetProcAddress", Ptr, hModule, AStr, "SendMessageW", Ptr)
   , NumPut(pWaitForSingleObject, ptr*1)
   , NumPut(pSendMessageW, ptr + A_PtrSize)
   if (A_PtrSize = 4)  {
      NumPut(0x68, ptr + 8, "UChar")
      , NumPut(Timeout, ptr + 9, "UInt"), NumPut(0x68, ptr + 13, "UChar")
      , NumPut(Handle, ptr + 14), NumPut(0x15FF, ptr + 18, "UShort")
      , NumPut(ptr, ptr + 20), NumPut(0x6850, ptr + 24, "UShort")
      , NumPut(Handle, ptr + 26), NumPut(0x68, ptr + 30, "UChar")
      , NumPut(Msg, ptr + 31, "UInt"), NumPut(0x68, ptr + 35, "UChar")
      , NumPut(hWnd, ptr + 36), NumPut(0x15FF, ptr + 40, "UShort")
      , NumPut(ptr+4, ptr + 42), NumPut(0xC2, ptr + 46, "UChar"), NumPut(4, ptr + 47, "UShort")
   }
   else  {
      NumPut(0x53, ptr + 16, "UChar")
      , NumPut(0x20EC8348, ptr + 17, "UInt"), NumPut(0xBACB8948, ptr + 21, "UInt")
      , NumPut(Timeout, ptr + 25, "UInt"), NumPut(0xB948, ptr + 29, "UShort")
      , NumPut(Handle, ptr + 31), NumPut(0x15FF, ptr + 39, "UShort")
      , NumPut(-45, ptr + 41, "UInt"), NumPut(0xB849, ptr + 45, "UShort")
      , NumPut(Handle, ptr + 47), NumPut(0xBA, ptr + 55, "UChar")
      , NumPut(Msg, ptr + 56, "UInt"), NumPut(0xB948, ptr + 60, "UShort")
      , NumPut(hWnd, ptr + 62), NumPut(0xC18941, ptr + 70, "UInt")
      , NumPut(0x15FF, ptr + 73, "UShort"), NumPut(-71, ptr + 75, "UInt")
      , NumPut(0x20C48348, ptr + 79, "UInt"), NumPut(0xC35B, ptr + 83, "UShort")
   }
   return ptr + A_PtrSize*2
}

16

Re: AHK: Скрипт застывает при открытии окна загрузки файла на сайт

В функции UnFreeze() ничего криминального нет, а в целом не могу сказать, особенно учитывая, что IE может работать сейчас неполноценно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder