2009-01-27 22 views
15

Necesito evitar que el control .NET WebBrowser muestre "¿Desea abrir o guardar este archivo?" y los diálogos "Guardar como". En cambio, quiero mostrar un cuadro de mensaje que le diga a los usuarios que las descargas de archivos están deshabilitadas por razones de seguridad.¿Cómo bloquear las descargas en el control .NET WebBrowser?

Comencé con el evento FileDownload de WebBrowser, pero no permite la cancelación. Luego, utilicé el enfoque de CodeProject: Extended .NET 2.0 WebBrowser Control para implementar mi propio evento basado en la llamada COM original utilizando la interfaz DWebBrowserEvents2. Cuando arreglé el código de acuerdo con an MS knowledge base entry about a bug with the FileDownload signature, se llamó al controlador de eventos y pude cancelar la descarga.

Esto no funciona con todas las descargas, sin embargo: descargar URL que apunta a una dirección URL que incluyen .exe provocar el evento y se puede cancelar antes de que aparezca el cuadro de diálogo - pero para otros (como .do), el controlador de eventos no se llama hasta que el el usuario hace clic en Open, Save o Cancel en el cuadro de diálogo.

Una posible solución podría ser la de intercept WH_CALLWNDPROCRET messages and 'answer' the dialog before it is shown to the user, pero suena como mucho esfuerzo y yo también preferiría una solución más limpia ...

¿Alguien sabe cómo bloquear de forma fiable todas las descargas?

+0

Déjame llegar a este punto ... ¿Quieres permitir el acceso a Internet para tus usuarios (que no es más que descargar archivos en la computadora) y quieres bloquear TODAS las descargas? – Sergio

+0

@Sergio: Creo que Jens quiere bloquear todos los archivos, que no se pueden mostrar directamente en webbrowser. – TcKs

+0

TcKs es correcto, quiero bloquear todo lo que no se puede mostrar. El objetivo no es evitar las descargas, sino evitar que se muestren los cuadros de diálogo "Guardar archivo como" para que el usuario no tenga acceso al disco duro. Mi aplicación está instalada como el shell de Windows (sin Explorer, sin menú de inicio). –

Respuesta

3

Puede usar el evento Navigating que permite la cancelación.

Dentro de este evento, puede tratar de conectarse a la URL que se está navegando usted mismo, inspeccionar los encabezados de respuesta http y cancelar la navegación si se detecta ContentType inapropiado.

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..."); 
} 

Obviamente, esto no es a prueba de balas solución, pero le puede dar una idea de cómo empezar (si no te importa pequeña ida y vuelta extra sólo para recuperar las cabeceras de respuesta HTTP).

Jens Bannmann escribió:

Esto no es ideal, ya que estoy tratando con aplicaciones web donde el solicitud adicional podría desencadenar una acción que se lleva a cabo dos veces :-(

Luego crearía un servidor proxy simple que inspeccionaría todos los datos recibidos y filtraría todas las respuestas http que podrían desencadenar el diálogo "Guardar como" en el control del navegador web.

Simplemente, no permita que su control del navegador web acceda directamente a Internet, pero delegue todas las solicitudes http a su servidor proxy especial que filtrará todas las respuestas inseguras de la web.

+0

Hmm, conectar un proxy en lugar de bloquear/deshabilitar de algún modo el diálogo no me parece una solución elegante. De todas formas, ¿podría agregar un proxy sin instalar software adicional, es decir, solo usando .NET Framework? –

+0

Creo que es una solución bastante elegante y tiene sentido. Además, su código no se romperá repentinamente con futuras versiones de IE. Puede implementar un servidor proxy simple dentro de su propio software. Si no sabes cómo hacerlo, publica otra pregunta, obtendrás más respuestas. –

+0

un proxy no funcionará de manera confiable ya que no podrá ver la url o los encabezados de las conexiones https. – Malcolm

3

La única manera fiable parece ser la de gancho en la cola de eventos de Windows y suprimir los cuadros de diálogo (como todo tipo de cosas puede obtener el acceso del usuario).Esto es lo que hace nuestra clase de ayuda:

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 es la clase de diálogo
  • # 32768 es el menú emergente
  • el espacio de nombres es WinAPI nuestros envoltorios PInvoke.

Si no desea bloquear todos los cuadros de diálogo, deberá agregar algunos filtros adicionales una vez que haya atrapado la clase. Depende de qué tan seguro debe estar. En $ WORK necesitamos bloquear todas las cargas y descargas.

Suprimir el menú emergente es necesario ya que da acceso a la aplicación de Ayuda, que ofrece enlaces al sitio web de microsoft, que permite el lanzamiento de una instancia completa de IE. Entonces pueden hacer lo que quieran.

+0

Bueno, esta publicación podría ayudar si ha agregado el código de clase WinAPI. = ( –

+0

Ha pasado un tiempo, pero creo que acabamos de utilizar pinvoke.net para crear las envolturas para lo que necesitábamos. – Malcolm

Cuestiones relacionadas