2016-09-16 73 views
1

问题

我正在创建一个应用程序来自动化Web应用程序。为了编写这个程序,我使用了OLE自动化(COM)。该网站的一个令人讨厌的部分是,当它检索数据时,JavaScript挂起。要尝试检测JavaScript引擎何时能够再次使用,我尝试设置然后读取一个变量。见下面我的代码:使用OLE自动访问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我得到的错误Unknown name事情。为了克服这个问题,我找到了错误并再次尝试(因为我认为这是JavaScript引擎悬挂的时候)。

然而console.log(foo)运行正常......因此,这意味着JSEngine不挂...

最后,我已经得到了非常卡住。有谁知道如何解决这个问题?

+0

我不知道如何使用自动热键做到这一点,我会去了解一下挂上由控制生成的事件。这是[Perl中的示例](http://perltricks.com/article/139/2014/12/11/Automated-Internet-Explorer-screenshots-using-Win32--OLE /)。 –

+0

哇...... Perl与我以前所使用的Perl不同:O – Sancarn

回答

1

试试这个:

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) 
     } 
    } 
} 
+0

Drat。就像我想使用ActiveX窗口一样,我不能伤心。当我这样做时,我登录到我们的网站并运行一个报告,它再次要求我登录并重新执行整个过程! – Sancarn

+0

好的,检查更新。 – errorseven

+0

那么我认为它的第二个例子不适合你?如果确实如此,请将其标记为已回答,以便其他人可以从中找到并受益。 – errorseven