2

ページをレンダリングした後でも、script タグとタグ内の関連する属性を削除するとうまくいくと思いましたが、うまくいきませんでした。

次のコードは script タグと onclick 属性を削除しますが、効果はありません。

何か案が?

私は避けたい:

  • 管理者権限が必要なため、レジストリを編集します。
  • コードが複雑になるため、Web コンテンツを個別にフェッチし、doc.write() を使用します。

ファイル:

  • javascript.html
  • test.ahk

javascript.html

<!DOCTYPE html>
<html>
    <head>
        <script> function displayDate() { document.getElementById("demo").innerHTML=Date(); }</script>
    </head>
    <body>
        <p id="demo" onclick="displayDate()">This is a paragraph. Click here.</p>
    </body>
</html> 

test.ahk

    Gui, Add, ActiveX, vWB w400 h300, Shell.Explorer  
    Gui, Show, w420 h320
    WB.Navigate("file:///" A_ScriptDir "/javascript.html")
    Loop
       Sleep 10
    Until (WB.readyState=4 && WB.document.readyState="complete" && !WB.busy)        

    doc := WB.document
    nodeScript := doc.getElementsByTagName("script")[0]
    nodeScript.parentNode.removeChild(nodeScript)
    nodeP := doc.getElementsByTagName("p")[0]
    nodeP.removeAttribute("onclick") 

    msgbox % doc.documentElement.outerHTML
    Return
4

1 に答える 1

0

IOleClientSite3 つの特定の COM インターフェイス ( 、IServiceProviderおよびIInternetSecurityManager) を実装し、コントロールの IOleObject インターフェイスの SetClientSite メソッドを呼び出すことにより、特定の WebBrowser コントロールに対してスクリプトを強制的に有効または無効にすることができます。

最終的には、メソッドを実装する必要がありますIInternetSecurityManager::ProcessUrlActiondwActionパラメータを に設定して WebBrowser がそれを呼び出すと、URLACTION_SCRIPT_RUNを設定*pPolicyURLPOLICY_DISALLOWてスクリプトを禁止するか、スクリプトを有効にし、ポリシーを適用するために (ゼロ) をURLPOLICY_ALLOW返すことができます。S_OK

SetWBClientSite()必要なコードを以下に示します。これは、コントロールの作成後、ナビゲートする前に呼び出すだけで実装できます。グローバル変数WBには、WebBrowser コントロールへの参照が含まれている必要があります。

/*  Complex workaround to override "Active scripting" setting
 *  and ensure scripts can't run within the WebBrowser control.
 */

global WBClientSite

SetWBClientSite()
{
    interfaces := {
    (Join,
        IOleClientSite: [0,3,1,0,1,0]
        IServiceProvider: [3]
        IInternetSecurityManager: [1,1,3,4,8,7,3,3]
    )}
    unkQI      := RegisterCallback("WBClientSite_QI", "Fast")
    unkAddRef  := RegisterCallback("WBClientSite_AddRef", "Fast")
    unkRelease := RegisterCallback("WBClientSite_Release", "Fast")
    WBClientSite := {_buffers: bufs := {}}, bufn := 0, 
    for name, prms in interfaces
    {
        bufn += 1
        bufs.SetCapacity(bufn, (4 + prms.MaxIndex()) * A_PtrSize)
        buf := bufs.GetAddress(bufn)
        NumPut(unkQI,       buf + 1*A_PtrSize)
        NumPut(unkAddRef,   buf + 2*A_PtrSize)
        NumPut(unkRelease,  buf + 3*A_PtrSize)
        for i, prmc in prms
            NumPut(RegisterCallback("WBClientSite_" name, "Fast", prmc+1, i), buf + (3+i)*A_PtrSize)
        NumPut(buf + A_PtrSize, buf + 0)
        WBClientSite[name] := buf
    }
    global wb
    if pOleObject := ComObjQuery(wb, "{00000112-0000-0000-C000-000000000046}")
    {   ; IOleObject::SetClientSite
        DllCall(NumGet(NumGet(pOleObject+0)+3*A_PtrSize), "ptr"
            , pOleObject, "ptr", WBClientSite.IOleClientSite, "uint")
        ObjRelease(pOleObject)
    }
}

WBClientSite_QI(p, piid, ppvObject)
{
    static IID_IUnknown := "{00000000-0000-0000-C000-000000000046}"
    static IID_IOleClientSite := "{00000118-0000-0000-C000-000000000046}"
    static IID_IServiceProvider := "{6d5140c1-7436-11ce-8034-00aa006009fa}"
    iid := _String4GUID(piid)
    if (iid = IID_IOleClientSite || iid = IID_IUnknown)
    {
        NumPut(WBClientSite.IOleClientSite, ppvObject+0)
        return 0 ; S_OK
    }
    if (iid = IID_IServiceProvider)
    {
        NumPut(WBClientSite.IServiceProvider, ppvObject+0)
        return 0 ; S_OK
    }
    NumPut(0, ppvObject+0)
    return 0x80004002 ; E_NOINTERFACE
}

WBClientSite_AddRef(p)
{
    return 1
}

WBClientSite_Release(p)
{
    return 1
}

WBClientSite_IOleClientSite(p, p1="", p2="", p3="")
{
    if (A_EventInfo = 3) ; GetContainer
    {
        NumPut(0, p1+0) ; *ppContainer := NULL
        return 0x80004002 ; E_NOINTERFACE
    }
    return 0x80004001 ; E_NOTIMPL
}

WBClientSite_IServiceProvider(p, pguidService, piid, ppvObject)
{
    static IID_IUnknown := "{00000000-0000-0000-C000-000000000046}"
    static IID_IInternetSecurityManager := "{79eac9ee-baf9-11ce-8c82-00aa004ba90b}"
    if (_String4GUID(pguidService) = IID_IInternetSecurityManager)
    {
        iid := _String4GUID(piid)
        if (iid = IID_IInternetSecurityManager || iid = IID_IUnknown)
        {
            NumPut(WBClientSite.IInternetSecurityManager, ppvObject+0)
            return 0 ; S_OK
        }
        NumPut(0, ppvObject+0)
        return 0x80004002 ; E_NOINTERFACE
    }
    NumPut(0, ppvObject+0)
    return 0x80004001 ; E_NOTIMPL
}

WBClientSite_IInternetSecurityManager(p, p1="", p2="", p3="", p4="", p5="", p6="", p7="", p8="")
{
    if (A_EventInfo = 5) ; ProcessUrlAction
    {
        if (p2 = 0x1400) ; dwAction = URLACTION_SCRIPT_RUN
        {
            NumPut((URLPOLICY_DISALLOW := 3), p3+0)  ; *pPolicy := URLPOLICY_DISALLOW
            return 0 ; S_OK
        }
    }
    return 0x800C0011 ; INET_E_DEFAULT_ACTION
}

_String4GUID(pGUID)
{
    VarSetCapacity(String,38*2)
    DllCall("ole32\StringFromGUID2", "ptr", pGUID, "str", String, "int", 39)
    Return  String
}

URLPOLICY_ALLOW現在の AutoHotkey インストーラーには、(3)ではなく (0)を設定することを除いて、これと同じコードが含まれていますURLPOLICY_DISALLOW。これは、スクリプトが無効になっているシステムでインストーラーを動作させるために必要でした。

ご覧のとおり、COM インターフェイスを AutoHotkey スクリプトに直接実装するのは簡単なことではありません。プレーン C では少し簡単で (プレーン CでのCOM を参照)、C++ でははるかに簡単です。

于 2013-03-02T08:43:40.423 に答える