17

我需要阻止 .NET WebBrowser 控件显示任何“您要打开还是保存此文件?” 和“另存为”对话框。相反,我想显示一个消息框,告诉用户出于安全原因禁用文件下载。

我从 的FileDownload事件开始WebBrowser,但它不允许取消。然后,我使用CodeProject 中的方法:Extended .NET 2.0 WebBrowser Control在原始 COM 调用的基础上使用 interface 实现我自己的事件DWebBrowserEvents2。当我根据有关 FileDownload 签名错误的 MS 知识库条目修复代码时,事件处理程序被调用并且我能够取消下载。

但是,这不适用于所有下载:下载指向 URL 的 URL,包括.exe引发事件,并且可以在对话框出现之前取消 - 但对于其他人(如.do),事件处理程序在用户单击之前不会被调用OpenSave或者Cancel在对话。

一个可能的解决方案可能是在向用户显示之前拦截WH_CALLWNDPROCRET消息并“回答”对话框,但这听起来很费力,我也更喜欢更清洁的解决方案......

有人知道如何可靠地阻止所有下载吗?

4

3 回答 3

3

唯一可靠的方法似乎是挂接到 Windows 事件队列并抑制对话框(因为各种事情都可以让用户访问)。这就是我们的助手类所做的:

    void ListenForDialogCreation()
    {
        // Listen for name change changes across all processes/threads on current desktop...
        _WinEventHook = WinAPI.SetWinEventHook(WinAPI.EVENT_OBJECT_CREATE, procDelegate);
    }
    void StopListeningForDialogCreation()
    {
        WinAPI.UnhookWinEvent(_WinEventHook);
    }

    void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        const uint OBJID_WINDOW = 0;
        const uint CHILDID_SELF = 0;

        // filter out non-HWND, and things not children of the current application
        if (idObject != OBJID_WINDOW || idChild != CHILDID_SELF)
            return;

        //Get the window class name
        StringBuilder ClassName = new StringBuilder(100);
        WinAPI.GetClassName(hwnd, ClassName, ClassName.Capacity);

        // Send close message to any dialog
        if (ClassName.ToString() == "#32770")
        {
            WinAPI.SendMessage(hwnd, WinAPI.WM.CLOSE, IntPtr.Zero, IntPtr.Zero);
            if (OnDialogCancelled != null)
                OnDialogCancelled();
        }
        if (ClassName.ToString() == "#32768")
        {
            WinAPI.SendMessage(hwnd, WinAPI.WM.CLOSE, IntPtr.Zero, IntPtr.Zero);
            if (OnDialogCancelled != null)
                OnDialogCancelled();
        }

    }

    public delegate void OnDialogCancelledEvent();
    public event OnDialogCancelledEvent OnDialogCancelled;
  • #32770 是 Dialog 类
  • #32768 是弹出菜单
  • WinAPI 命名空间是我们的 pinvoke 包装器。

如果您不想阻止所有 Dialogs,您需要在上完课程后添加一些额外的过滤器。这取决于您需要有多安全。在 $WORK,我们需要阻止所有上传和下载。

抑制弹出菜单是必要的,因为它可以访问帮助应用程序,该应用程序提供指向微软网站的链接,从而可以启动 IE 的完整实例。然后他们可以为所欲为。

于 2013-06-17T21:44:03.770 回答
3

您可以使用Navigating允许取消的事件。

在此事件中,您可以尝试连接到自己正在导航的 URL,检查 http 响应标头并在检测到不适当的 ContentType 时取消导航。

System.Net.WebRequest request = System.Net.WebRequest.Create(e.Url);

// we need only header part of http response
request.Method = "HEAD";

System.Net.WebResponse response = request.GetResponse();

// only text/html, text/xml, text/plain are allowed... extend as required
if (!response.ContentType.StartsWith("text/"))
{
  e.Cancel = true;
  MessageBox.Show("Not allowed for security resons...");
}

显然,这不是万无一失的解决方案,但可以让您了解如何开始(如果您不介意为了检索 http 响应标头而进行额外的微小往返)。

延斯班曼写道:

这并不理想,因为我正在处理额外请求可能触发执行两次操作的 Web 应用程序:-(

然后,我将创建一些简单的代理服务器来检查所有接收到的数据,并过滤掉所有可能触发 Web 浏览器控件中的“另存为”对话框的 http 响应。

简单地说,不要让您的网络浏览器控制直接访问互联网,而是将所有 http 请求委托给您的特殊代理服务器,该代理服务器将过滤掉来自网络的所有不安全响应。

于 2009-01-28T07:22:09.417 回答
0

这个项目 - http://www.codeproject.com/Articles/157329/Http-Monitor-for-Webbrowser-Control允许拦截和检查来自 WebBrowser 控件的 HTTP 流量。

然后你可以通过 MIME 过滤数据,只允许 html、图像、脚本等。

于 2012-01-21T20:18:01.267 回答