UWSCでウインドウハンドルからCOMオブジェクトを取得する
公式掲示板で、GetAllWinで取得できるのに、GetActiveOleObjが失敗するケースがあがっていた。
初期adminユーザーだと特定条件下でなるようなのだけど、原因は不明。
それにともなって、いろいろと調べたところ、IEを別ユーザーで起動すると、同じような状況になることがわかった。
で、別ユーザーで起動したIEのCOMオブジェクトが取得できないか、調べてみた。
どうやら「Internet Explorer_Server」のウインドウハンドルにメッセージを送ると、IHTMLDocument2オブジェクトが取得できるらしい。
スクリプトを書いてみた。
OPTION EXPLICIT IFB GET_UWSC_NAME = "ie_getObject.uws" THEN DIM wid = GETID("", "IEFrame") DIM ie = IeObject.Get(wid) PRINT wid + ":" + ie + ":" + ie.document.URL ENDIF MODULE IeObject DEF_DLL RegisterWindowMessageA(string): dword: user32 DEF_DLL SendMessageTimeoutA(dword, dword, dword, dword, dword, dword, var dword): dword: user32 DEF_DLL ObjectFromLresult(dword, {dword, dword, dword, dword}, dword, var dword): dword: oleacc CONST CLASS_NAME = "Internet Explorer_Server" DIM _nMsg PROCEDURE IeObject _nMsg = RegisterWindowMessageA("WM_HTML_GETOBJECT") FEND FUNCTION GetIEServerHND(wid) RESULT = 0 IFB STATUS(wid, ST_CLASS) = CLASS_NAME THEN RESULT = IDTOHND(wid) ELSE DIM wids = -1, i FOR i = 0 TO GETALLWIN(wid) - 1 IFB STATUS(ALL_WIN_ID[i], ST_CLASS) = CLASS_NAME THEN wids = ALL_WIN_ID[i] BREAK ENDIF NEXT IF wids > -1 THEN RESULT = IDTOHND(wids) ENDIF FEND FUNCTION Get(wid) RESULT = 0 DIM lRes = 0 IFB SendMessageTimeoutA(GetIEServerHnd(wid), _nMsg, 0, 0, 2, 1000, lRes) THEN DIM ptr = 0 // EXTERN_C const IID IID_IHTMLDocument2 = {0x332C4425,0x26CB,0x11D0,{0xB4,0x83,0x00,0xC0,0x4F,0xD9,0x01,0x19}}; IFB lRes > 0 AND ObjectFromLresult(lRes, $332C4425, $11D026CB, $C00083B4, $1901D94F, 0, ptr) >= 0 THEN IFB ptr > 0 THEN DIM htdoc = VARTYPE(ptr, VAR_DISPATCH) COM_ERR_IGN RESULT = htdoc.parentWindow COM_ERR_RET ENDIF ENDIF ENDIF FEND ENDMODULE
IID_IHTMLDocument2があれであっているのかは不明。
手元のXP環境では動作する。
IHTMLDocument2からIWebBrowser2の取得方法はQueryServiceとかするらしいのだけど、親でいいか、と適当に判断。
VARTYPEの型変換を初めて有効に使った気がする。
でも、肝心の別ユーザーのIEオブジェクトは取れなかった、、、。
多分、権限関連の処理が不足しているんじゃないか、とは思うのだけど、、、。
今のところは、以下のような関係。
ログインユーザー | IE起動ユーザー | UWSC起動ユーザー | GetActiveOleObj | 本スクリプト |
---|---|---|---|---|
ユーザーA | ユーザーA | ユーザーA | ○ | ○ |
ユーザーA | ユーザーB | ユーザーA | × | × |
ユーザーA | ユーザーB | ユーザーB | × | ○ |
ユーザーA | ユーザーA | ユーザーB | × | × |
このスクリプトが優位なのは、IEとUWSCが別ユーザーの場合に、オブジェクトが取れる、ということでしょうか。
あんまり役に立たない、、、。