如何在.NET WebBrowser控件中阻止下载?

时间:2009-01-27 12:42:12

标签: .net browser download

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

我从FileDownload WebBrowser事件开始,但不允许取消。然后,我使用CodeProject: Extended .NET 2.0 WebBrowser Control中的方法,使用接口DWebBrowserEvents2基于原始COM调用实现自己的事件。当我根据an MS knowledge base entry about a bug with the FileDownload signature修复代码时,调用了事件处理程序,我就可以取消下载了。

但这不适用于所有下载:指向包含.exe的网址的下载网址会引发事件,并且可以在对话框出现之前取消 - 但对于其他人(例如.do),在用户点击对话框中的OpenSaveCancel之前,系统不会调用事件处理程序。

可能的解决方案可能是intercept WH_CALLWNDPROCRET messages and 'answer' the dialog before it is shown to the user,但这听起来很费劲,我也更喜欢更清洁的解决方案......

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

3 个答案:

答案 0 :(得分:3)

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

在此活动的内部,您可以尝试连接到自己导航的网址,检查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响应头)。

  

Jens Bannmann写道:

     

这与我正在处理的情况并不理想   网络应用程序的额外   请求可能触发一个动作   进行了两次: - (

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

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

答案 1 :(得分: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包装器。

如果您不想阻止所有对话,那么一旦您上课,您就会想要添加一些额外的过滤器。这取决于您需要多么安全。在$ WORK,我们需要阻止所有上传和下载。

禁止弹出菜单是必要的,因为它可以访问帮助应用程序,该应用程序提供了指向微软网站的链接,该网站可以启动IE的完整实例。然后他们可以做任何他们想做的事。

答案 2 :(得分:0)

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

然后,您可以按MIME过滤数据,只允许使用html,图像,脚本等。