javascript - 使用 OLE 自动化访问 Javascript 变量

标签 javascript internet-explorer com autohotkey ole

问题

我目前正在创建一个应用程序来自动化 Web 应用程序。为了编写这个程序,我使用 OLE 自动化 (COM)。该网站令人烦恼的部分之一是,当它检索数据时,JavaScript 会挂起。为了尝试检测 JavaScript 引擎何时能够再次使用,我尝试设置然后读取一个变量。请参阅下面的代码:

IE := ComObjCreate("InternetExplorer.Application")
IE.Visible := 1
IE.Navigate("about:blank")
sleep,1000
javascript =
(
console.log('testing foo')
var foo = "hello"
alert(foo)
)


TryTillPass(IE,javascript)

RunJS(COM,javascript){
    js := javascript . ";"
    js := StrReplace(js,"`r",";") 
    js := StrReplace(js,"`n",";") 
    js := StrReplace(js,";;",";") 

    COM.Navigate("javascript:" js)
}

TryTillPass(COM,javascript){
    x := COM.Name
    Msgbox, %x%
Test:
    Try {
        RunJS(COM,javascript)
        jvar := COM.document.parentWindow.foo
        console.log(foo)
    } Catch e {
        msgbox, Error:%e%
        Sleep,1000
        GoTo Test
    }

    return jvar
}

令我困惑的是,每当我运行 COM.document.parentWindow.foo 时,我都会收到错误未知名称。为了尝试克服这个问题,我捕获了错误并重试(因为我假设这是 JavaScript 引擎挂起的时候......)。

但是 console.log(foo) 运行良好...所以这意味着 JSEngine 没有挂起...

最终我陷入了困境。有谁知道如何解决这个问题吗?

最佳答案

试试这个:

Gui, Add, ActiveX, w800 h800 vwb, Shell.Explorer
wb.Navigate("about:blank")
Gui, Show
while wb.busy
    sleep 10
window := wb.document.parentWindow
return

F1::
javascript =
(
console.log('testing foo')
var foo = "hello"
alert(foo)
)
    window.execScript(javascript)  ; This injects the code
    msgbox % window.foo     ; Access the Value in AutoHotkey
    return

GuiClose:
    ExitApp

示例2:

IE := ComObjCreate("InternetExplorer.Application")
IE.Visible := 1
IE.Navigate("about:blank")

javascript =
(
console.log('testing foo')
var foo = "hello"
alert(foo)
)
sleep 1000

myReturnVar := IE_InjectJS(WinExist("ahk_class IEFrame"), javascript, "foo")

MsgBox % myReturnVar

return

IE_InjectJS(hWnd_MainWindow, JS_to_Inject="", VarNames_to_Return="", COM_to_Call1="", COM_to_Call2="") {

   window := _win(hWnd_MainWindow)

   wb := WBGet("ahk_id" hWnd_MainWindow)

   if COM_to Call1 
   {
    ;MsgBox, 4096,, COM_to_Call1 is: %COM_to_Call1%, 4       
    Loop, Parse, COM_to_Call1, `, 
    {
    ;MsgBox, 4096,, A_LoopField is: %A_LoopField%, 4
        wb[A_LoopField]     
    }    
   }     

   if JS_to_Inject
      window.execScript(JS_to_Inject)

   if VarNames_to_Return
      Loop, Parse, VarNames_to_Return, `,
      {
         Loop, Parse, A_LoopField, .
            result := (A_Index=1? window:result)[A_LoopField]
         Ret .= result ","
      }

   if COM_to_Call2 
   {
    ;MsgBox, 4096,, COM_to_Call2 is: %COM_to_Call2%, 4                 
    Loop, Parse, COM_to_Call2, `, 
    {
    ;MsgBox, 4096,, A_LoopField is: %A_LoopField%, 4
    wb[A_LoopField]     
    }               
   }  

   return SubStr(Ret,1,-1)
}

_win(hwnd, Svr#=1) {               ;// based on ComObjQuery docs

   static msg := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT")
        , IID1 := "{0002DF05-0000-0000-C000-000000000046}"  ; IID_IWebBrowserApp
        , IID2 := "{332C4427-26CB-11D0-B483-00C04FD90119}"  ; IID_IHTMLWindow2

   SendMessage msg, 0, 0, Internet Explorer_Server1, ahk_id %hwnd%

   if (ErrorLevel != "FAIL") {

      lResult:=ErrorLevel, VarSetCapacity(GUID,16,0)

      if DllCall("ole32\CLSIDFromString", "wstr","{332C4425-26CB-11D0-B483-00C04FD90119}", "ptr",&GUID) >= 0 {

         DllCall("oleacc\ObjectFromLresult", "ptr",lResult, "ptr",&GUID, "ptr",0, "ptr*",pdoc)

            return  ComObj(9,ComObjQuery(pwb:=ComObjQuery(pdoc,IID1,IID1),IID2,IID2),1)
                ,   ObjRelease(pdoc), ObjRelease(pwb)

      }

   }

}

WBGet(WinTitle="ahk_class IEFrame", Svr#=1) {               ;// based on ComObjQuery docs
   static msg := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT")
        , IID := "{0002DF05-0000-0000-C000-000000000046}"   ;// IID_IWebBrowserApp
;//     , IID := "{332C4427-26CB-11D0-B483-00C04FD90119}"   ;// IID_IHTMLWindow2
   SendMessage msg, 0, 0, Internet Explorer_Server%Svr#%, %WinTitle%
   if (ErrorLevel != "FAIL") {
      lResult:=ErrorLevel, VarSetCapacity(GUID,16,0)
      if DllCall("ole32\CLSIDFromString", "wstr","{332C4425-26CB-11D0-B483-00C04FD90119}", "ptr",&GUID) >= 0 {
         DllCall("oleacc\ObjectFromLresult", "ptr",lResult, "ptr",&GUID, "ptr",0, "ptr*",pdoc)
         return ComObj(9,ComObjQuery(pdoc,IID,IID),1), ObjRelease(pdoc)
      }
   }
}

关于javascript - 使用 OLE 自动化访问 Javascript 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39534365/

相关文章:

javascript - jquery 根据选定的下拉值循环进行计算

javascript - PHP for-each 循环不起作用?

javascript - 仅选择一个复选框并为选中的输入添加类

reactjs - 适用于 Internet Explorer 10 及更低版本的 React、WebPack 和 Babel 生成 SCRIPT1002 : Syntax error

javascript - 在非 WebKit 浏览器中推迟 JavaScript 执行

com - 需要有关 iTunes COM 持久 ID 的解释。将轨道传输到 iPod 时,轨道 ID 是否相同?

javascript - 如何使用 Knockout.js 将下拉列表中的选定项目自动更新到 SignalR 中的所有已连接客户端?

html - 删除 HTML 按钮/提交的完整样式

c++ - 在 WM_CREATE 中设置接口(interface)指针,在 WM_COMMAND 中变为 NULL

c# - 如何使用word interop判断两个word文档是否相同