2

我正在尝试使用 CoInternetSetFeatureEnabled API 来阻止提示对话框,如下所示,它在托管 WebBrowser 控件的应用程序中显示,但它不起作用。按照MSDN - Internet Feature Controls (I..L)更新注册表也不起作用。我在 Win7 64 位上使用 IE9。

FEATURE_BLOCK_INPUT_PROMPTS Internet Explorer 7. 启用或禁用弹出窗口阻止程序以显示输入提示对话框。使用弹出窗口阻止程序来降低欺骗的风险。

private const int FEATURE_BLOCK_INPUT_PROMPTS = 27;

[DllImport("urlmon.dll")]
[PreserveSig]
[return: MarshalAs(UnmanagedType.Error)]
public static extern int CoInternetSetFeatureEnabled(
    int FeatureEntry,
    [MarshalAs(UnmanagedType.U4)] int dwFlags,
    bool fEnable);

public static int disableInputPrompts(bool state)
{
    return CoInternetSetFeatureEnabled(
       FEATURE_BLOCK_INPUT_PROMPTS, SET_FEATURE_ON_PROCESS, state);
}

更新刚刚在 WinXP 中用 IE8 尝试过,这个功能正在工作。它取决于其他东西吗?

更新根据 msdn,此功能在 IE9 中默认启用,但它不起作用。单击w3schools 示例中的“试用”按钮会启动提示对话框,这是一个安全漏洞吗?

默认情况下,此功能对 Internet Explorer 启用,对托管 WebBrowser 控件的应用程序禁用。

关于如何在 WebBrowser 控件中阻止提示对话框的任何可行替代方法?

这可以通过实现自定义安全管理器 IInternetSecurityManager 来完成吗?

4

1 回答 1

0

我现在唯一的选择是使用 SetWindowsHookEx,它基于Suppressing Hosted WebBrowser Control Dialogs示例。

internal static class WindowsInterop
{
    private const Int32 WM_COMMAND = 0x0111;
    private const Int32 WM_INITDIALOG = 0x0110;

    private const Int32 WM_SYSCOMMAND = 0x0112;
    private const Int32 SC_CLOSE = 0xF060;

    private static IntPtr _pWH_CALLWNDPROCRET = IntPtr.Zero;

    private static HookProcedureDelegate _WH_CALLWNDPROCRET_PROC =
        new HookProcedureDelegate(WindowsInterop.WH_CALLWNDPROCRET_PROC);

    [DllImport("user32.dll")]
    private static extern IntPtr SetWindowsHookEx(Int32 hooktype, 
        HookProcedureDelegate callback, IntPtr hMod, UInt32 dwThreadId);

    [DllImport("user32.dll")]
    private static extern IntPtr UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll")]
    private static extern Int32 CallNextHookEx(IntPtr hhk, Int32 nCode, 
        IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern Int32 GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern Int32 GetWindowText(IntPtr hWnd, 
        StringBuilder text, Int32 maxLength);

    [DllImport("user32.dll", SetLastError = false)]
    private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, 
        IntPtr wParam, IntPtr lParam);

    // Hook Types
    private const Int32 WH_CALLWNDPROCRET = 12;


    [StructLayout(LayoutKind.Sequential)]
    private struct CWPRETSTRUCT
    {
        public IntPtr lResult;
        public IntPtr lParam;
        public IntPtr wParam;
        public UInt32 message;
        public IntPtr hwnd;
    };

    // Delegate for a WH_ hook procedure
    private delegate Int32 HookProcedureDelegate(Int32 iCode, 
        IntPtr pWParam, IntPtr pLParam);

    // Delegate for the EnumChildWindows method
    private delegate Boolean EnumerateWindowDelegate(IntPtr pHwnd, IntPtr pParam);

    // Add a Hook into the CALLWNDPROCRET notification chain
    internal static void Hook()
    {
        if (WindowsInterop._pWH_CALLWNDPROCRET == IntPtr.Zero)
        {
            WindowsInterop._pWH_CALLWNDPROCRET = SetWindowsHookEx(
                WH_CALLWNDPROCRET,
                    WindowsInterop._WH_CALLWNDPROCRET_PROC,
                        IntPtr.Zero,
                            (uint)AppDomain.GetCurrentThreadId());
        }
    }

    // Remove the Hook into the CALLWNDPROCRET notification chain
    internal static void Unhook()
    {
        if (WindowsInterop._pWH_CALLWNDPROCRET != IntPtr.Zero)
        {
            UnhookWindowsHookEx(WindowsInterop._pWH_CALLWNDPROCRET);
        }
    }

    // Hook proceedure called by the OS when a message has been processed by the target Window
    private static Int32 WH_CALLWNDPROCRET_PROC(Int32 iCode, 
        IntPtr pWParam, IntPtr pLParam)
    {
        if (iCode < 0)
            return CallNextHookEx(WindowsInterop._pWH_CALLWNDPROCRET, 
                iCode, pWParam, pLParam);

        CWPRETSTRUCT cwp = (CWPRETSTRUCT)
            Marshal.PtrToStructure(pLParam, typeof(CWPRETSTRUCT));

        Console.WriteLine(cwp.message);

        if (cwp.message == WM_INITDIALOG)
        {
            // A dialog was initialised, find out what sort it was via it's Caption text
            Int32 iLength = GetWindowTextLength(cwp.hwnd);
            StringBuilder sb = new StringBuilder(iLength + 1);

            GetWindowText(cwp.hwnd, sb, sb.Capacity);
            var title = sb.ToString();
            if (String.IsNullOrEmpty(title) == false && 
                title.IndexOf("prompt", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                // just close it
                SendMessage(cwp.hwnd, WM_SYSCOMMAND, new IntPtr(SC_CLOSE), IntPtr.Zero);
                return 1;
            }
        }

        // Call the next hook in the chain
        return CallNextHookEx(WindowsInterop._pWH_CALLWNDPROCRET, iCode, pWParam, pLParam);
    }
}
于 2013-02-14T02:22:52.247 回答