2009-01-27 35 views
15

我需要防止.NET WebBrowser控件显示任何“您想打开还是保存此文件?”和“另存为”对话框。相反,我想显示一个消息框,告诉用户出于安全原因禁用了文件下载。如何在.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修复代码时,事件处理程序被调用,我可以取消下载。但是,这并不适用于所有下载,但是:下载指向URL的URL(包括.exe)会引发事件并可能在对话框出现之前被取消 - 但对于其他人(如.do),事件处理程序不会在调用用户在对话框中单击OpenSaveCancel

一种可能的解决办法可能是intercept WH_CALLWNDPROCRET messages and 'answer' the dialog before it is shown to the user,但它听起来像很多努力,我也希望能有一个清晰的解决方案......

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

+0

让我得到这个海峡......你想允许你的用户访问互联网(这不过是把文件下载到电脑里),你想阻止所有的下载? – Sergio 2009-01-27 12:56:13

+0

@Sergio:我想,Jens想阻止所有文件,这些文件不能直接在webbrowser中显示。 – TcKs 2009-01-27 14:05:41

+0

TcKs是正确的,我想阻止无法显示的所有内容。重点不在于防止下载,而是为了防止任何“保存文件为”对话框显示,以便用户无法访问硬盘。我的应用程序被安装为Windows外壳程序(没有资源管理器,没有开始菜单)。 – 2009-01-29 06:30:10

回答

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响应头)。

延Bannmann写道:

这不是理想的,因为我处理 Web应用程序,其中额外 请求可能触发一个动作被 :-(

进行两次

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

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

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中,我们需要阻止所有上传和下载。

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