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

如何在.NET WebBrowser控件中阻止下载?,.net,browser,download,.net,Browser,Download,我需要防止.NET WebBrowser控件显示任何“是否打开或保存此文件?”和“另存为”对话框。相反,我想显示一个消息框,告诉用户出于安全原因禁用文件下载 我从WebBrowser的FileDownload事件开始,但它不允许取消。然后,我使用来自的方法,使用接口DWebBrowserEvents2基于原始COM调用实现自己的事件。当我根据修复代码时,调用了事件处理程序,我可以取消下载 但这并不适用于所有下载:下载指向URL(包括.exe的URL)的URL会引发事件,并且可以在对话框出现之前取

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

我从
WebBrowser
FileDownload
事件开始,但它不允许取消。然后,我使用来自的方法,使用接口
DWebBrowserEvents2
基于原始COM调用实现自己的事件。当我根据修复代码时,调用了事件处理程序,我可以取消下载

但这并不适用于所有下载:下载指向URL(包括
.exe
的URL)的URL会引发事件,并且可以在对话框出现之前取消-但对于其他URL(如
.do
),只有用户单击对话框中的
打开
保存
取消
),才会调用事件处理程序

一个可能的解决方案可能是,但这听起来像是很大的努力,我也更喜欢一个更干净的解决方案


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

您可以使用允许取消的
导航事件

在此事件中,您可以尝试连接到自己正在导航的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浏览器控件中触发“另存为”对话框的所有http响应

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

此项目-允许拦截和检查来自web浏览器控制的http流量


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

唯一可靠的方法似乎是挂接到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是对话框类
  • #32768是弹出式菜单
  • WinAPI名称空间是我们的pinvoke包装器
如果您不想阻止所有对话框,那么在捕获该类后,您需要添加一些额外的过滤器。这取决于您需要的安全程度。在$WORK中,我们需要阻止所有上载和下载


抑制弹出菜单是必要的,因为它可以访问“帮助”应用程序,该应用程序提供指向microsoft网站的链接,从而可以启动完整的IE实例。然后他们可以做任何他们想做的事情。

让我明白这一点……您想允许您的用户访问internet吗(这只不过是将文件下载到计算机中)你想阻止所有下载吗?@Sergio:我想,Jens想阻止所有不能直接在webbrowser.TcKs中显示的文件。没错,我想阻止所有不能显示的文件。重点不是阻止下载,而是阻止任何“将文件另存为”对话框显示,用户无法访问硬盘。我的应用程序作为windows外壳安装(没有资源管理器,没有开始菜单).Hmm,连接代理而不是以某种方式阻止/禁用对话框对我来说并不是一个优雅的解决方案。无论如何,我可以在不安装其他软件的情况下添加代理,即仅使用.NET framework吗?我认为这是一个非常优雅的解决方案,很有意义。而且你的代码不会突然与未来版本的IE发生冲突。你可以吗在您自己的软件中实现简单代理服务器。如果您不知道如何实现,请发布另一个问题,您将获得更多答案。代理无法可靠地工作,因为它无法查看https连接的url或标题。如果您添加了WinAPI类代码,此帖子可能会有所帮助=(已经有一段时间了,但我认为我们只是使用pinvoke.net来创建我们需要的包装。