2009-01-27 66 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實例。然後他們可以做任何他們想做的事。