1

Тема: AHK: Как войти на mail.ru - с разными логинами и паролями

Добрый день.
У меня несколько почтовых ящиков в mail.ru.
И возник вопрос - как заходить на них - одним запуском скрипта.

Вопрос такой:
Как зайти на на сайт mail.ru (через google chrome) - с логином tws1238  и паролем 12345678 ?
И затем также зайти на тот же сайт, но уже с паролем tws7235 и паролем 09876543 ?

То есть войти нужно как-то -  и в том случае, когда вход пока не осуществлен, и также в том случае - когда вход уже выполнен.

2

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Да в принципе всё просто. Изучаете эту библиотеку и эмулируете с её помощью действия пользователя при входе в аккаунт и выходе.

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

3 (изменено: Malcev, 2019-09-08 19:12:08)

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Я бы использовал Selenium:
https://www.autohotkey.com/boards/viewt … mp;t=32323
из-за
https://www.autohotkey.com/boards/viewt … 16#p218916

4

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Если проблема только в скорости превращения строки JSON в AHK-объект, то с моим вариантом класса JSON будет гораздо быстрее.

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

5

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Насколько быстрее?
Давай на примере:

driver:= ComObjCreate("Selenium.ChromeDriver")
driver.Get("http://delfi.lv")
a := A_TickCount
OuterHtml := driver.PageSource()
msgbox % A_TickCount - a

Через Selenium 186 ms.
Через автоитовскую функцию использующую машинный код парсера JSMN - 270 ms.
https://www.autoitscript.com/forum/topi … n-udf-jsmn

6

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Я не пробовал применить свой JSON к этой библиотеке, но на форуме сравнивали скорости той, что там, и моей. Получалось раз в 10 быстрее.
Так что сравнить можем только на примере какой-то конкретной JSON-строки.

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

7

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

А зачем сравнивать скорость той, что сейчас используется и твоей?
Та что сейчас используется на delfi.lv вообще глохнет.

ChromeInst := new Chrome()
PageInst := ChromeInst.GetPage()
PageInst.Call("Page.navigate", {"url": "http://delfi.lv"})
PageInst.WaitForLoad()

a := a_tickcount
RootNode := PageInst.Call("DOM.getDocument").root
OuterHTML := PageInst.Call("DOM.getOuterHTML", {"nodeId": RootNode.nodeId}).OuterHTML
msgbox % a_tickcount - a

Надо сравнивать скорость выполнения твоей c Selenium или с автоитовской.

8

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Господа, извините что отвлекаю от научной беседы.

Скажите, а мне простому парню - какой код применять ?

9

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Malcev, ну, как руки дойдут, попробую присобачить свой JSON к Chrome.ahk.
radioamator, лично у меня готового кода нет. Если сами не хотите заморачиваться с изучением всяких библиотек, составляйте ТЗ, определяйтесь с ценой и пишите здесь, ну или мне в личку можете.

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

10

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

radioamator, если нужно получать исходный код страницы, то с текущим парсером JSON, используемым в chrome.ahk могут быть заметные тормоза.
С другой стороны, если делать через Selenium, то возможно придется обновлять chromedriver при обновлении хрома, а возможно его и модернизировать:
http://forum.script-coding.com/viewtopic.php?id=13837
Также через данный враппер селениума нельзя выполнить некоторые методы, которые можно через Chrome DevTools Protocol.

11

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Malcev пишет:

если нужно получать исходный код страницы

Да там не надо исходный код получать. Нужен, как я понимаю, просто доступ к элементам страницы через DOM.

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

12

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Ну если просто доступ к элементам, то разница незаметна.

13

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Malcev пишет:

radioamator, если нужно получать исходный код страницы, то с текущим парсером JSON, используемым в chrome.ahk могут быть заметные тормоза.

Да мне лишь бы скриптом просто в почту зайти и все.

14

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

radioamator


#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance force 

; https://florentbr.github.io/SeleniumBasic/ - webdriver


url := "https://mail.ru/"

login1 := "tws1238"
pass1 := "12345678"

login2 := "tws7235"
pass2 := "09876543"


driver := ComObjCreate("Selenium.ChromeDriver")
driver.AddArgument("--disable-infobars")


driver.Get(url)

driver.findElementById("mailbox:login").SendKeys(login1).SendKeys(driver.Keys.Enter)
sleep 200
driver.findElementById("mailbox:password").SendKeys(pass1).SendKeys(driver.Keys.Enter)


driver.ExecuteScript("window.open();")
driver.SwitchToNextWindow
driver.Get(url)


driver.findElementById("mailbox:login").SendKeys(login2).SendKeys(driver.Keys.Enter)
sleep 200
driver.findElementById("mailbox:password").SendKeys(pass2).SendKeys(driver.Keys.Enter)



    
    Esc::
    {
     driver.Quit()
	ExitApp
  }

15 (изменено: Malcev, 2019-09-12 23:02:58)

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Быстрее посылать значения через джаваскрипт:

login := "blah-blah"
driver:= ComObjCreate("Selenium.ChromeDriver")
element := driver.findElementByCss("input[name=""email""]")
driver.ExecuteScript("arguments[0].value=""" login """;", element)

Также можно посылать клики:

element := driver.findElementByCss("input[name=""login""]")
driver.ExecuteScript("arguments[0].click();", element)

16

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

teadrinker пишет:

Malcev, ну, как руки дойдут, попробую присобачить свой JSON к Chrome.ahk.

Как поклоннику Вашего творчества, мне, было бы чрезвычайно интересно испытать такой образец!

OFF:
Коллеги, с Днём Программиста!

17

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Спасибо, и Вас!
Сейчас как раз работаю с DevTools Protocol, может, и дойдут.

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

18

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Спасибо, всех с праздником!
KusochekDobra, если скорость JSON  от teadrinker устраивать не будет, то при большом желании и наличии достаточного количества свободного времени можно и автоитовскую библиотеку на автохотки перенести.

19

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

inseption86, что-то запускаю этот скрипт.
В трее он вроде висит, но ничего не делает.

Как же открыть нужную почту в браузере google chrome?
Браузер на момент запуска скрипта - открыт.

20 (изменено: teadrinker, 2019-09-16 03:44:46)

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

KusochekDobra пишет:

было бы чрезвычайно интересно испытать такой образец

Можно тестировать:

if !item := Chrome.FindInstances() {
   MsgBox, Не найден Chrome`, запущенный в debug mode
   ExitApp
}
ChromeInst := {"base": Chrome, "DebugPort": item.port}

WinActivate, % "ahk_pid" item.PID
pages := ChromeInst.GetPageList()

found := ""
for i, page in pages
   continue
until RegExMatch(page.url, "delfi.lv") && found := true
if !found {
   MsgBox, Страница с http://delfi.lv не найдена
   ExitApp
}

pageInst := new Chrome.Page( page.webSocketDebuggerUrl )
pageInst.Call("Page.bringToFront")
pageInst.WaitForLoad()

a := a_tickcount
RootNode := PageInst.Call("DOM.getDocument").root
OuterHTML := PageInst.Call("DOM.getOuterHTML", {"nodeId": RootNode.nodeId}).OuterHTML
msgbox % a_tickcount - a
MsgBox, % OuterHTML
ExitApp

class Chrome
{
   static DebugPort := 9222
   
   /*
      Escape a string in a manner suitable for command line parameters
   */
   CliEscape(Param)
   {
      return """" RegExReplace(Param, "(\\*)""", "$1$1\""") """"
   }
   
   FindInstances()
   {
      static Needle := "--remote-debugging-port=(\d+)"
      Out := {}
      for k, PID in EnumProcessesByName("chrome.exe")
         cmd := GetCommandLine(PID).cmd
      until found := RegExMatch(cmd, Needle, Match)
      Return found ? {port: Match1, PID: PID} : ""
   }
   
   /*
      ProfilePath - Path to the user profile directory to use. Will use the standard if left blank.
      URLs        - The page or array of pages for Chrome to load when it opens
      Flags       - Additional flags for chrome when launching
      ChromePath  - Path to chrome.exe, will detect from start menu when left blank
      DebugPort   - What port should Chrome's remote debugging server run on
   */
   __New(ProfilePath:="", URLs:="about:blank", Flags:="", ChromePath:="", DebugPort:="")
   {
      ; Verify ProfilePath
      if (ProfilePath != "" && !InStr(FileExist(ProfilePath), "D"))
         throw Exception("The given ProfilePath does not exist")
      this.ProfilePath := ProfilePath
      
      ; Verify ChromePath
      if (ChromePath == "")
         FileGetShortcut, %A_StartMenuCommon%\Programs\Google Chrome.lnk, ChromePath
      if (ChromePath == "")
         RegRead, ChromePath, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe
      if !FileExist(ChromePath)
         throw Exception("Chrome could not be found")
      this.ChromePath := ChromePath
      
      ; Verify DebugPort
      if (DebugPort != "")
      {
         if DebugPort is not integer
            throw Exception("DebugPort must be a positive integer")
         else if (DebugPort <= 0)
            throw Exception("DebugPort must be a positive integer")
         this.DebugPort := DebugPort
      }
      
      ; Escape the URL(s)
      for Index, URL in IsObject(URLs) ? URLs : [URLs]
         URLString .= " " this.CliEscape(URL)
      
      Run, % this.CliEscape(ChromePath)
      . " --remote-debugging-port=" this.DebugPort
      . (ProfilePath ? " --user-data-dir=" this.CliEscape(ProfilePath) : "")
      . (Flags ? " " Flags : "")
      . URLString
      ,,, OutputVarPID
      this.PID := OutputVarPID
   }
   
   /*
      End Chrome by terminating the process.
   */
   Kill()
   {
      Process, Close, % this.PID
   }
   
   /*
      Queries chrome for a list of pages that expose a debug interface.
      In addition to standard tabs, these include pages such as extension
      configuration pages.
   */
   GetPageList()
   {
      http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
      http.open("GET", "http://127.0.0.1:" this.DebugPort "/json")
      http.send()
      return JSON.Parse(http.responseText)
   }
   
   GetActivePage(fnCallback := "")  {
      Return new this.Page( this.GetPageList()[1, "webSocketDebuggerUrl"], fnCallback )
   }
   
   /*
      Returns a connection to the debug interface of a page that matches the
      provided criteria. When multiple pages match the criteria, they appear
      ordered by how recently the pages were opened.
      
      Key        - The key from the page list to search for, such as "url" or "title"
      Value      - The value to search for in the provided key
      MatchMode  - What kind of search to use, such as "exact", "contains", "startswith", or "regex"
      Index      - If multiple pages match the given criteria, which one of them to return
      fnCallback - A function to be called whenever message is received from the page
   */
   GetPageBy(Key, Value, MatchMode:="exact", Index:=1, fnCallback:="")
   {
      Count := 0
      for n, PageData in this.GetPageList()
      {
         if (((MatchMode = "exact" && PageData[Key] = Value) ; Case insensitive
            || (MatchMode = "contains" && InStr(PageData[Key], Value))
            || (MatchMode = "startswith" && InStr(PageData[Key], Value) == 1)
            || (MatchMode = "regex" && PageData[Key] ~= Value))
            && ++Count == Index)
            return new this.Page(PageData.webSocketDebuggerUrl, fnCallback)
      }
   }
   
   /*
      Shorthand for GetPageBy("url", Value, "startswith")
   */
   GetPageByURL(Value, MatchMode:="startswith", Index:=1, fnCallback:="")
   {
      return this.GetPageBy("url", Value, MatchMode, Index, fnCallback)
   }
   
   /*
      Shorthand for GetPageBy("title", Value, "startswith")
   */
   GetPageByTitle(Value, MatchMode:="startswith", Index:=1, fnCallback:="")
   {
      return this.GetPageBy("title", Value, MatchMode, Index, fnCallback)
   }
   
   /*
      Shorthand for GetPageBy("type", Type, "exact")
      
      The default type to search for is "page", which is the visible area of
      a normal Chrome tab.
   */
   GetPage(Index:=1, Type:="page", fnCallback:="")
   {
      return this.GetPageBy("type", Type, "exact", Index, fnCallback)
   }
   
   /*
      Connects to the debug interface of a page given its WebSocket URL.
   */
   class Page
   {
      Connected := False
      ID := 0
      Responses := []
      
      /*
         wsurl      - The desired page's WebSocket URL
         fnCallback - A function to be called whenever message is received
      */
      __New(wsurl, fnCallback:="")
      {
         this.fnCallback := fnCallback
         this.BoundKeepAlive := this.Call.Bind(this, "Browser.getVersion",, False)
         
         ; TODO: Throw exception on invalid objects
         if IsObject(wsurl)
            wsurl := wsurl.webSocketDebuggerUrl
         
         wsurl := StrReplace(wsurl, "localhost", "127.0.0.1")
         this.ws := {"base": this.WebSocket, "_Event": this.Event, "Parent": this}
         this.ws.__New(wsurl)
         
         while !this.Connected
            Sleep, 50
      }
      
      /*
         Calls the specified endpoint and provides it with the given
         parameters.
         
         DomainAndMethod - The endpoint domain and method name for the
         endpoint you would like to call. For example:
         PageInst.Call("Browser.close")
         PageInst.Call("Schema.getDomains")
         
         Params - An associative array of parameters to be provided to the
         endpoint. For example:
         PageInst.Call("Page.printToPDF", {"scale": 0.5 ; Numeric Value
         , "landscape": JSON.true ; Boolean Value
         , "pageRanges: "1-5, 8, 11-13"}) ; String value
         PageInst.Call("Page.navigate", {"url": "https://autohotkey.com/"})
         
         WaitForResponse - Whether to block until a response is received from
         Chrome, which is necessary to receive a return value, or whether
         to continue on with the script without waiting for a response.
      */
      Call(DomainAndMethod, Params:="", WaitForResponse:=True)
      {
         if !this.Connected
            throw Exception("Not connected to tab")
         
         ; Use a temporary variable for ID in case more calls are made
         ; before we receive a response.
         ID := this.ID += 1
         
         this.ws.Send(JSON.Stringify({"id": ID
         , "params": Params ? Params : {}
         , "method": DomainAndMethod}))
         
         if !WaitForResponse
            return
         
         ; Wait for the response
         this.responses[ID] := False
         while !this.responses[ID]
            Sleep, 50
         
         ; Get the response, check if it's an error
         response := this.responses.Delete(ID)
         if (response.error)
            throw Exception("Chrome indicated error in response",, JSON.Stringify(response.error))
         
         return response.result
      }
      
      /*
         Run some JavaScript on the page. For example:
         
         PageInst.Evaluate("alert(""I can't believe it's not IE!"");")
         PageInst.Evaluate("document.getElementsByTagName('button')[0].click();")
      */
      Evaluate(JS)
      {
         response := this.Call("Runtime.evaluate",
         ( LTrim Join
         {
            "expression": JS,
            "objectGroup": "console",
            "includeCommandLineAPI": JSON.true,
            "silent": JSON.false,
            "returnByValue": JSON.false,
            "userGesture": JSON.true,
            "awaitPromise": JSON.false
         }
         ))
         
         if (response.exceptionDetails)
            throw Exception(response.result.description,, JSON.Stringify(response.exceptionDetails))
         
         return response.result
      }
      
      /*
         Waits for the page's readyState to match the DesiredState.
         
         DesiredState - The state to wait for the page's ReadyState to match
         Interval     - How often it should check whether the state matches
      */
      WaitForLoad(DesiredState:="complete", Interval:=100)
      {
         while this.Evaluate("document.readyState").value != DesiredState
            Sleep, Interval
      }
      
      /*
         Internal function triggered when the script receives a message on
         the WebSocket connected to the page.
      */
      Event(EventName, Event)
      {
         ; If it was called from the WebSocket adjust the class context
         if this.Parent
            this := this.Parent
         
         ; TODO: Handle Error events
         if (EventName == "Open")
         {
            this.Connected := True
            BoundKeepAlive := this.BoundKeepAlive
            SetTimer, %BoundKeepAlive%, 15000
         }
         else if (EventName == "Message")
         {
            data := JSON.Parse(Event.data)
            
            ; Run the callback routine
            fnCallback := this.fnCallback
            if (newData := %fnCallback%(data))
               data := newData
            
            if this.responses.HasKey(data.ID)
               this.responses[data.ID] := data
         }
         else if (EventName == "Close")
         {
            this.Disconnect()
         }
         else if (EventName == "Error")
         {
            throw Exception("Websocket Error!")
         }
      }
      
      /*
         Disconnect from the page's debug interface, allowing the instance
         to be garbage collected.
         
         This method should always be called when you are finished with a
         page or else your script will leak memory.
      */
      Disconnect()
      {
         if !this.Connected
            return
         
         this.Connected := False
         this.ws.Delete("Parent")
         this.ws.Disconnect()
         
         BoundKeepAlive := this.BoundKeepAlive
         SetTimer, %BoundKeepAlive%, Delete
         this.Delete("BoundKeepAlive")
      }
      
      class WebSocket
      {
         __New(WS_URL)
         {
            static wb
            
            ; Create an IE instance
            Gui, +hWndhOld
            Gui, New, +hWndhWnd
            this.hWnd := hWnd
            Gui, Add, ActiveX, vWB, Shell.Explorer
            WB.Silent := true
            Gui, %hOld%: Default
            
            ; Write an appropriate document
            WB.Navigate("about:<!DOCTYPE html><meta http-equiv='X-UA-Compatible'"
            . "content='IE=edge'><body></body>")
            while (WB.ReadyState < 4)
               sleep, 50
            this.document := WB.document
            
            ; Add our handlers to the JavaScript namespace
            this.document.parentWindow.ahk_savews := this._SaveWS.Bind(this)
            this.document.parentWindow.ahk_event := this._Event.Bind(this)
            this.document.parentWindow.ahk_ws_url := WS_URL
            
            ; Add some JavaScript to the page to open a socket
            Script := this.document.createElement("script")
            Script.text := "ws = new WebSocket(ahk_ws_url);`n"
            . "ws.onopen = function(event){ ahk_event('Open', event); };`n"
            . "ws.onclose = function(event){ ahk_event('Close', event); };`n"
            . "ws.onerror = function(event){ ahk_event('Error', event); };`n"
            . "ws.onmessage = function(event){ ahk_event('Message', event); };"
            this.document.body.appendChild(Script)
         }
         
         ; Called by the JS in response to WS events
         _Event(EventName, Event)
         {
            this["On" EventName](Event)
         }
         
         ; Sends data through the WebSocket
         Send(Data)
         {
            this.document.parentWindow.ws.send(Data)
         }
         
         ; Closes the WebSocket connection
         Close(Code:=1000, Reason:="")
         {
            this.document.parentWindow.ws.close(Code, Reason)
         }
         
         ; Closes and deletes the WebSocket, removing
         ; references so the class can be garbage collected
         Disconnect()
         {
            if this.hWnd
            {
               this.Close()
               Gui, % this.hWnd ": Destroy"
               this.hWnd := False
            }
         }
      }
   }
}

EnumProcessesByName(procName) {
   if !DllCall("Wtsapi32\WTSEnumerateProcesses", Ptr, 0, UInt, 0, UInt, 1, PtrP, pProcessInfo, PtrP, count)
      throw Exception("WTSEnumerateProcesses failed. A_LastError: " . A_LastError)
   
   addr := pProcessInfo, PIDs := []
   Loop % count  {
      if StrGet( NumGet(addr + 8) ) = procName
         PID := NumGet(addr + 4, "UInt"), PIDs.Push(PID)
      addr += A_PtrSize = 4 ? 16 : 24
   }
   DllCall("Wtsapi32\WTSFreeMemory", Ptr, pProcessInfo)
   Return PIDs
}

GetCommandLine(PID, SetDebugPrivilege := false, GetImagePath := false) {
   static SetDebug := 0, PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0
   
   if (SetDebugPrivilege && !SetDebug)  {
      if !res := SeDebugPrivilege()
         SetDebug := 1
      else  {
         MsgBox, 4, Ошибка SeDebugPrivilege(), Не удалось установить привилегии.`nОшибка %res%`nПродолжить?
         IfMsgBox, No
            Return
      }
   }
   hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
   (A_Is64bitOS && DllCall("IsWow64Process", Ptr, hProc, UIntP, IsWow64))
   if (!A_Is64bitOS || IsWow64)
      PtrSize := 4, PtrType := "UInt", pPtr := "UIntP", offsetCMD := 0x40
   else
      PtrSize := 8, PtrType := "Int64", pPtr := "Int64P", offsetCMD := 0x70

   hModule := DllCall("GetModuleHandle", "str", "Ntdll", Ptr)
   if (A_PtrSize < PtrSize)  {            ; скрипт 32, целевой процесс 64
      if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64QueryInformationProcess64", Ptr)
         failed := "NtWow64QueryInformationProcess64"
      if !ReadProcessMemory := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64ReadVirtualMemory64", Ptr)
         failed := "NtWow64ReadVirtualMemory64"
      info := 0, szPBI := 48, offsetPEB := 8
   }
   else  {
      if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtQueryInformationProcess", Ptr)
         failed := "NtQueryInformationProcess"
      ReadProcessMemory := "ReadProcessMemory"
      if (A_PtrSize > PtrSize)            ; скрипт 64, целевой процесс 32
         info := 26, szPBI := 8, offsetPEB := 0
      else                                ; скрипт и целевой процесс одной битности
         info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
   }
   if failed  {
      DllCall("CloseHandle", Ptr, hProc)
      MsgBox, Не удалось получить указатель на функцию %failed%
      Return
   }
   VarSetCapacity(PBI, 48, 0)
   if DllCall(QueryInformationProcess, Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, UIntP, bytes) != STATUS_SUCCESS  {
      DllCall("CloseHandle", Ptr, hProc)
      Return
   }
   pPEB := NumGet(&PBI + offsetPEB, PtrType)
   DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pPEB + PtrSize * 4, pPtr, pRUPP, PtrType, PtrSize, UIntP, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD, UShortP, szCMD, PtrType, 2, UIntP, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD + PtrSize, pPtr, pCMD, PtrType, PtrSize, UIntP, bytes)
   
   VarSetCapacity(buff, szCMD, 0)
   DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pCMD, Ptr, &buff, PtrType, szCMD, UIntP, bytes)
   obj := { cmd: StrGet(&buff, "UTF-16") }
   
   if (GetImagePath && obj.cmd)  {
      DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD - PtrSize*2, UShortP, szPATH, PtrType, 2, UIntP, bytes)
      DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD - PtrSize, pPtr, pPATH, PtrType, PtrSize, UIntP, bytes)
      
      VarSetCapacity(buff, szPATH, 0)
      DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pPATH, Ptr, &buff, PtrType, szPATH, UIntP, bytes)
      obj.path := StrGet(&buff, "UTF-16") . (IsWow64 ? " *32" : "")
   }
   DllCall("CloseHandle", Ptr, hProc)
   Return obj
}

SeDebugPrivilege()  {
   static PROCESS_QUERY_INFORMATION := 0x400, TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2
   
   hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION, Int, false, UInt, DllCall("GetCurrentProcessId"), Ptr)
   DllCall("Advapi32\OpenProcessToken", Ptr, hProc, UInt, TOKEN_ADJUST_PRIVILEGES, PtrP, token)
   
   DllCall("Advapi32\LookupPrivilegeValue", Ptr, 0, Str, "SeDebugPrivilege", Int64P, luid)
   VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
   NumPut(1, TOKEN_PRIVILEGES, "UInt")
   NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
   NumPut(SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, 12, "UInt")
   DllCall("Advapi32\AdjustTokenPrivileges", Ptr, token, Int, false, Ptr, &TOKEN_PRIVILEGES, UInt, 0, Ptr, 0, Ptr, 0)
   res := A_LastError
   DllCall("CloseHandle", Ptr, token)
   DllCall("CloseHandle", Ptr, hProc)
   Return res  ; в случае удачи 0
}

class JSON
{
   static JS := JSON._GetJScriptObject(), true := {}, false := {}, null := {}
   
   Parse(sJson, js := false)  {
      if jsObj := this.VerifyJson(sJson)
         Return js ? jsObj : this._CreateObject(jsObj)
   }
   
   Stringify(obj, js := false, indent := "") {
      if js
         Return this.JS.JSON.stringify(obj, "", indent)
      else {
         sObj := this._ObjToString(obj)
         Return this.JS.eval("JSON.stringify(" . sObj . ",'','" . indent . "')")
      }
   }
   
   GetKey(sJson, key, indent := "") {
      if !this.VerifyJson(sJson)
         Return
      
      try Return this.JS.eval("JSON.stringify((" . sJson . ")" . (SubStr(key, 1, 1) = "[" ? "" : ".") . key . ",'','" . indent . "')")
      catch
         MsgBox, Bad key:`n`n%key%
   }
   
   SetKey(sJson, key, value, indent := "") {
      if !this.VerifyJson(sJson)
         Return
      if !this.VerifyJson(value, true) {
         MsgBox, % "Bad value: " . value                      . "`n"
                 . "Must be a valid JSON string."             . "`n"
                 . "Enclose literal strings in quotes '' or """".`n"
                 . "As an empty string pass '' or """""
         Return
      }
      try {
         res := this.JS.eval( "var obj = (" . sJson . ");"
                            . "obj" . (SubStr(key, 1, 1) = "[" ? "" : ".") . key . "=" . value . ";"
                            . "JSON.stringify(obj,'','" . indent . "')" )
         this.JS.eval("obj = ''")
         Return res
      }
      catch
         MsgBox, Bad key:`n`n%key%
   }
   
   RemoveKey(sJson, key, indent := "") {
      if !this.VerifyJson(sJson)
         Return
      
      sign := SubStr(key, 1, 1) = "[" ? "" : "."
      try {
         if !RegExMatch(key, "(.*)\[(\d+)]$", match)
            res := this.JS.eval("var obj = (" . sJson . "); delete obj" . sign . key . "; JSON.stringify(obj,'','" . indent . "')")
         else
            res := this.JS.eval( "var obj = (" . sJson . ");" 
                               . "obj" . (match1 != "" ? sign . match1 : "") . ".splice(" . match2 . ", 1);"
                               . "JSON.stringify(obj,'','" . indent . "')" )
         this.JS.eval("obj = ''")
         Return res
      }
      catch
         MsgBox, Bad key:`n`n%key%
   }
   
   Enum(sJson, key := "", indent := "") {
      if !this.VerifyJson(sJson)
         Return
      
      conc := key ? (SubStr(key, 1, 1) = "[" ? "" : ".") . key : ""
      try {
         jsObj := this.JS.eval("(" sJson ")" . conc)
         res := jsObj.IsArray()
         if (res = "")
            Return
         obj := {}
         if (res = -1) {
            Loop % jsObj.length
               obj[A_Index - 1] := this.JS.eval("JSON.stringify((" sJson ")" . conc . "[" . (A_Index - 1) . "],'','" . indent . "')")
         }
         else if (res = 0) {
            keys := jsObj.GetKeys()
            Loop % keys.length
               k := keys[A_Index - 1], obj[k] := this.JS.eval("JSON.stringify((" sJson ")" . conc . "['" . k . "'],'','" . indent . "')")
         }
         Return obj
      }
      catch
         MsgBox, Bad key:`n`n%key%
   }
   
   VerifyJson(sJson, silent := false) {
      try jsObj := this.JS.eval("(" sJson ")")
      catch {
         if !silent
            MsgBox, Bad JSON string:`n`n%sJson%
         Return
      }
      Return IsObject(jsObj) ? jsObj : true
   }
   
   _ObjToString(obj) {
      if IsObject( obj ) {
         for k, v in ["true", "false", "null"]
            if (obj = this[v])
               Return v
            
         isArray := true
         for key in obj {
            if IsObject(key)
               throw Exception("Invalid key")
            if !( key = A_Index || isArray := false )
               break
         }
         for k, v in obj
            str .= ( A_Index = 1 ? "" : "," ) . ( isArray ? "" : """" . k . """:" ) . this._ObjToString(v)

         Return isArray ? "[" str "]" : "{" str "}"
      }
      else if !(obj*1 = "" || RegExMatch(obj, "\s"))
         Return obj
      
      for k, v in [["\", "\\"], [A_Tab, "\t"], ["""", "\"""], ["/", "\/"], ["`n", "\n"], ["`r", "\r"], [Chr(12), "\f"], [Chr(08), "\b"]]
         obj := StrReplace( obj, v[1], v[2] )

      Return """" obj """"
   }

   _GetJScriptObject() {
      static doc
      doc := ComObjCreate("htmlfile")
      doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
      JS := doc.parentWindow
      JSON._AddMethods(JS)
      Return JS
   }

   _AddMethods(ByRef JS) {
      JScript =
      (
         Object.prototype.GetKeys = function () {
            var keys = []
            for (var k in this)
               if (this.hasOwnProperty(k))
                  keys.push(k)
            return keys
         }
         Object.prototype.IsArray = function () {
            var toStandardString = {}.toString
            return toStandardString.call(this) == '[object Array]'
         }
      )
      JS.eval(JScript)
   }

   _CreateObject(jsObj) {
      res := jsObj.IsArray()
      if (res = "")
         Return jsObj
      
      else if (res = -1) {
         obj := []
         Loop % jsObj.length
            obj[A_Index] := this._CreateObject(jsObj[A_Index - 1])
      }
      else if (res = 0) {
         obj := {}
         keys := jsObj.GetKeys()
         Loop % keys.length
            k := keys[A_Index - 1], obj[k] := this._CreateObject(jsObj[k])
      }
      Return obj
   }
}

На момент запуска скрипта уже должен быть запущенным Chrome в debug mode, страница http://delfi.lv должна быть уже загружена.

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

21

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Отличные результаты.
Предложи GeekDude заменить текущий парсер на твой.

22

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Так он давно в теме не отвечает. Посмотрел, его последний пост 21 Jan 2019.

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

23

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Да, кстати ещё изменён метод FindInstances() на winapi вместо WMI, тоже тормозило.

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

24

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

teadrinker, а мне-то как ?
У меня просто mail.ru ....

25

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

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

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

26

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

teadrinker, Ясно.

А как при помощи Chrome.ahk - войти в почту ?
Помогите, пожалуйста.

27

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Как войти готового кода нет, могу подсказать, как открыть вкладку с сайтом, если надо.

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

28 (изменено: inseption86, 2019-09-16 16:49:13)

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

radioamator

Скачать и установить - https://github.com/florentbr/SeleniumBasic/releases/download/v2.0.9.0/SeleniumBasic-2.0.9.0.exe
После, скачать и заменить файл - https://chromedriver.storage.googleapis.com/77.0.3865.40/chromedriver_win32.zip

29

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Malcev пишет:

Спасибо, всех с праздником!
KusochekDobra, если скорость JSON  от teadrinker устраивать не будет, то при большом желании и наличии достаточного количества свободного времени можно и автоитовскую библиотеку на автохотки перенести.

Да я больше не за скорость топлю, а за удобство. Хотя, одно, другому не мешает.
Как-то просто привык к тому, как вы(имею ввиду основной костяк "Серого форума"), выражаете свои решения кодом и, конечно, такое мнение можно смело считать субъективным, но я пребываю в убеждении, что ваши решения более развёрнуты, понятны. Что до момента финальной сборки они выдерживают больше "фильтров" самокритики и содержательных дискуссий, от чего, отождествляю их с наиболее отвечающими своим запросам. К тому же, это подтверждается временем.

30

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Malcev пишет:

Предложи GeekDude заменить текущий парсер на твой.

teadrinker пишет:

Так он давно в теме не отвечает. Посмотрел, его последний пост 21 Jan 2019.

Он объявился:
https://www.autohotkey.com/boards/viewt … 73#p296973

31

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

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

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

32

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Конечно, стоит выложить.
Так как парсер JSON от Coco весьма тормозит эту библиотеку.

33

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

teadrinker, тут возник вопрос по использованию JSON:
https://www.autohotkey.com/boards/viewt … 32#p299032

34

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Ответил.

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

35 (изменено: Malcev, 2020-05-29 05:44:20)

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

teadrinker, привязку твоего JSON к Хрому в 20 посте можно считать финальной?

36

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Проблема в том, что у некоторых пользователей такой код

JS := GetJScriptObject()
MsgBox, % JS.eval("2+2")

GetJScriptObject() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
   JS := doc.parentWindow
   JSON._AddMethods(JS)
   Return JS
}

при вызове eval выдаёт ошибку 0x80020006 — неизвестное имя (или ещё какую-то, не уверен). У меня ни на одном компьютере такой ошибки не возникало. Пробовал отключать скрипты в настройках IE — всё равно работает. Так что для публичных и коммерческих проектов пока использую старый (но доработанный) вариант.

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

37

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Можно так делать:

JS := GetJScriptObject()
MsgBox, % JS.eval("2+2")

GetJScriptObject() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
   JS := doc.parentWindow
   if (doc.documentMode < 9)
      JS.execScript("eval()")
   JSON._AddMethods(JS)
   Return JS
}

38

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

А почему получается documentMode меньше 9? Знаю, что на XP стоит восьмая версия, но об ошибках сообщали пользователи семёрки.

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

39

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Ну может у них IE9 не установлен.
Кстати, работает и так:

JS := GetJScriptObject()
MsgBox, % JS.eval("2+2")

GetJScriptObject() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
   JS := doc.parentWindow
   if (doc.documentMode < 9)
      JS.execScript()
   JSON._AddMethods(JS)
   Return JS
}

40

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Malcev пишет:

Ну может у них IE9 не установлен.

Теоретически возможно, конечно.
Ладно, спасибо, попробую при каком-нибудь обновлении.

Malcev пишет:

привязку твоего JSON к Хрому в 20 посте можно считать финальной?

Саму привязку можно с обсуждёнными оговорками, но класс Chrome нуждается в доработках.

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

41

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

А что с классом не так?Я потестировал, вроде работает.

42

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Иногда ошибку выдаёт при подключении к странице, не отслеживает закрытие инстанса. Ещё вроде какие-то ошибки возникали, сейчас точно не помню.

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

43

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Ты про последнюю его версию говоришь?
https://github.com/G33kDude/Chrome.ahk/releases/tag/1.2

44

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Эту не тестировал. Но тоже вижу, что закрытие инстанса не отслеживается, __Delete() не прописано, есть только Kill(). Посмотрю попозже, есть ли улучшения в работе.

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

45

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Автор chrome.ahk активизировался на форуме с новой поделкой, может создашь баг-репорт по его библотеке?

46

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Думаешь, он будет сейчас этим заниматься? Все баги трудновоспроизводимые, я до сих пор точно не понимаю причин, по которым они происходят, так что внятное описание будет составить проблематично. В своих скриптах просто делаю ещё одну попытку в случае ошибок.

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

47

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Ну если получится воспроизвести, то можно попытаться привлечь его внимание.

48

Re: AHK: Как войти на mail.ru - с разными логинами и паролями

Ещё пока не успел новую версию потестировать, попробую её сначала.

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