2009-09-30 26 views
5

Estoy usando el control WebBrowser en un proyecto de Windows forma C# y quería saber si hay limitaciones de cuántas instancias de dicha aplicación puede ejecutar al mismo tiempo. (En otras palabras, hace MSFT imponer más limitaciones que los límites máquina física - CPU/memoria, etc)Limitaciones de control de Webbrowser

+0

Acabo de publicar una respuesta (larga) sobre las limitaciones del control WebBrowser, y también quería corregir la idea de que el motor de renderización del control WebBrowser utiliza el motor de la versión IE instalada actualmente (ya que NO) , y describí cómo puede predecir y ver qué versión utiliza para procesar según lo que haya instalado. (ver mi respuesta) pero, básicamente, ya sea usó IE 4.0 o IE 7.0 para renderizar de forma predeterminada, esto es alterable a través del registro. aclamaciones. –

Respuesta

3

No hay limitaciones artificiales en el control WebBrowser.

Sin embargo, utiliza el motor de renderizado de IE (cualquier versión está instalada en la computadora del usuario final), por lo que utiliza bastante memoria.

¿Qué estás tratando de hacer?

Si está intentando escribir un navegador web, le recomiendo que utilice un mejor motor de representación, como WebKit o Gecko.

+2

Tal elección implica un conjunto de compensaciones. Si envías WebKit o Gecko , la instalación será más grande y tendrá que emitir parches cada vez que se encuentre una falla de seguridad con esos componentes. Por otro lado, los componentes de IE se actualizarán cuando se instalen las actualizaciones de IE. – EricLaw

+0

Verdadero. Sin embargo, usar el motor IE significa que va a aumentar la base de usuarios de IE6. http://mashable.com/2009/07/16/ie6-must-die/ – SLaks

+0

conozco bien los otros motores de renderizado, y los inconvenientes, sin embargo, los que necesito usar IE. La pregunta sigue siendo ¿cuáles son las limitaciones? También esperaba un problema de utilización de la memoria, pero cuando hice algunas pruebas por encima de 10 instancias llegué a algún tipo de pared ... y no era memoria, parecía estar relacionada con la CPU, pero eso no tenía sentido considerando que la máquina tenía 8 núcleos. – webly

0

Prueba este código y ver lo que sucede:

int count = 0; 
List<Form> forms = new List<Form>(); 
try 
{ 
    while (true) 
    { 
     Form f = new Form(); 
     WebBrowser wb = new WebBrowser(); 
     f.Controls.Add(wb); 
     f.Show(); 
     wb.Url = new Uri(@"http://www.stackoverflow.com"); 
     forms.Add(f); 
     count++; 
    } 
} 
catch 
{ 
    MessageBox.Show(count.ToString()); 
} 

voy a supongo que es cientos, sino No se.

+2

Mueva el try/catch fuera del bucle 'while', o nunca dejará de buclear. – SLaks

+1

@SLaks: hecho. Me has avergonzado :) En realidad estaba pensando que simplemente presionaría el botón 'stop' en Visual Studio una vez que apareciera MessageBox. – MusiGenesis

+1

@MusiGenesis odio que no podamos presionar detener cuando aparece un cuadro de mensaje, me ha obligado a cerrar el proceso devenv varias veces :(. –

38

Déjeme decirle algunas desventajas ...

[la mayor parte de los problemas mencionados aquí ha sido contestada o dirigidos a un cierto grado en mi sección de respuestas anterior en stackoverflow, si usted es curioso, se siente libre para navegar por mi Respuestas relacionadas con WebBrowser-Control].

  1. La detección cuando la página se hace realmente de carga es muy difícil de hacer fiable, de hecho, tiene que emplear una serie de cortes con el fin de ser capaz de hacer esto, algunos métodos e ideas ni siquiera se habló acerca de en línea y no se conocen, pero los años que he pasado luchando con este control, he descifrado algunas cosas y ¡he desarrollado una base de códigos para que funcione! Y lo hace, si necesita ayuda con esto, puedo proporcionar más detalles.

  2. Déjame decirte esto directamente. El motor de representación predeterminado en el control del navegador web está fijado para garantizar la compatibilidad en todas las plataformas .

    Básicamente, si está instalado el navegador es IE 7 - IE 9, entonces el motor de representación utilizado es solo IE 7.0 (de forma predeterminada).

    Si, sin embargo, la versión de IE instalado es IE 6 o menos, entonces el motor de renderizado utilizado es Internet Explorer 4.0 (no es broma), a menos que, por supuesto, configurar de otra manera.

    Existe la idea errónea de que el control WebBrowser usa lo que sea actualmente instalado (versión actual de IE), pero esto no es cierto, ya que lo hacen para reducir problemas de compatibilidad con versiones anteriores. Puede ver (como prueba) de que este es realmente su problema yendo a www.whatsmyuseragent.com en su navegador normal, y luego yendo a ese sitio web nuevamente en su control WebBrowser, verá que dice MSIE 7.0 :).

    Usted puede configurarlo para que utilice la versión actual instalada de Internet explorador, ya sea usando una etiqueta META en la página, o la edición del Registro en la máquina en el control WebBrowser se ejecutará (edición de CURRENT_USER y LOCAL_MACHINE se ambos trabajan).

    Por lo tanto, por razones de compatibilidad, las páginas se renderizarán en el modo Estándares IE7 de forma predeterminada. Para evitar que esto suceda, siga el enlace que he proporcionado a continuación que analizará tanto el método META Tag como el método de edición del registro para resolver este problema (para ambos sistemas 32 & de 64 bits). La solución se incluye como una respuesta a la pregunta de otra persona sobre una función que funciona de forma incorrecta o inesperada. Leer la pregunta no es necesario para interpretar/entender correctamente la respuesta. Aquí está el enlace:

    Script runs slower in the dotnet WebBrowser control (Ctrl + clic para abrir en la nueva pestaña).

  3. El sistema de eventos es bastante hacky, realmente necesita saber cosas que no se han documentado correctamente y algunas cosas que no se han documentado en absoluto. De hecho, lo he declarado como uno de los peores productos de MS, en términos del diseño del producto y también en términos de la falta de documentación decente que han puesto a disposición en él. Su documentación seca de estilo MSDN es ridícula.

  4. Los marcos incorrectos admiten, si hace una llamada a document.frames.length, solo obtendrá los marcos justo debajo del documento de nivel superior, no todos los marcos, tendrá que escribir sus propias funciones para obtener todo anidado marcos (infinitamente anidados) y lo he hecho, si necesita ayuda con él. La detección y referencia de marcos es muy importante y juega un papel vital para detectar cuándo la página realmente ha terminado de cargarse. En eso, usar .Busy y .ReadyState en el control WebBrowser no es suficiente. De hecho, no es suficiente.

  5. No existe un sistema incorporado para eliminar los cuadros de diálogo de JavaScript que aparecen en cada página, incluido el nuevo cuadro de diálogo IE9 que molesta a las personas con el mensaje "¿Estás seguro de que quieres abandonar esta página? He desarrollado rutinas para hacer esto y deshacerme de ellas, básicamente, uno de los métodos consiste en ejecutar JavaScript enviado desde el control WebBrowser a la página html que lo dirige para eliminar la alerta, confirmar, imprimir cuadros de diálogo (y también para obtener deshacerse del nuevo cuadro de diálogo IE 9 que mencioné anteriormente). Estos son posibles cuadros de diálogo provenientes solo de JS, y básicamente ejecuto JavaScript que le dice al navegador que la función .alert es nula (es decir, un método/función vacía que no hace nada), y hago exactamente lo mismo para todos estos 4 cuadros de diálogo que provienen de JavaScript. Por supuesto, si ha contado más de 4 cuadros (si ha contado más, no dude en hacérmelo saber). Además, hay un segundo método mediante el cual podemos hacer esto, y no solo evitará los cuadros de diálogo de JavaScritp, sino que cada cuadro de diálogo que podría/debería aparecer en el control del navegador web, este método usa WinHooks e intercepta el cuadro de diálogo antes se muestra, puede obtener tanta información como desee del cuadro de diálogo (su contenido como texto, título/título como texto, etc.) y decidir si desea que se muestre o cancelar su visualización, o incluso simular un clic en cualquier parte del cuadro de diálogo (es decir: cualquiera de sus botones) para que la pila piense que el diálogo de pregunta o información fue respondido correctamente. Este es un método interesante que he leído pero que aún no he probado, y estoy ansioso por comprender el proceso WinHook una vez que tenga algo de tiempo libre. Como de costumbre, si necesita ayuda, no dude en consultar algunas de mis respuestas anteriores a varias preguntas de control del navegador web, ya que he respondido muchas, y si eso no funciona, hágamelo saber. Tenga en cuenta que esto depende en gran medida de saber cuándo la página está completamente cargada, lo cual es muy difícil de hacer (pero es posible, utilizando métodos no documentados, de una manera 100% confiable). Entonces punto 1). Entrará en relevancia muchas veces.

  6. No hay manera confiable o sencilla de controlar la información de caché que se perpetúa o guarda, una vez más, debe desarrollar sus propias rutinas para hacer lo que desee con la información de caché, ya sea para filtrar, eliminar o intentar evitarlo para todos los tipos de caché, incluida la información del historial, las cookies y los archivos de caché reales almacenados en el sistema local. Si nos fijamos en DeleteUrlCacheEntry que le dará una pista sobre dos formas de hacerlo por su cuenta, también, estoy bastante seguro de que tengo algunas respuestas anteriores que hablan sobre cómo hacer esto en StackOverflow.Con DeleteUrlCacheEntry, puede jugar con elementos de caché que comienzan con la etiqueta "Cookie:", la etiqueta "Visited:" y los elementos que son simplemente direcciones de sitios web (comenzando con "http: //" y "https: //" (y sí, https está en caché; | al menos la información de ubicación es de todos modos.) También tenga en cuenta que esta información disponible a través de DeleteUrlCacheEntry (y la FindFirstUrlCacheEntry/FindNextUrlCacheEntry que se utiliza para recorrer todo el caché) no incluye su Internet actual elementos del historial del explorador. La lista de sitios "Visitado:" está separada de su lista de Historial real, que ve cuando hace clic en el símbolo * en la barra de menús de Internet Explorer y entra en la sección Historial (de la sección de favoritos). no estoy seguro de por qué lo han hecho así y cuál es la diferencia formal y exacta (y por qué hay una diferencia) pero está en la lista de cosas para descubrir (no dude en hacérnoslo saber en los comentarios). Porque, la La lista "Visitado:" es una lista de sitios que usted visitó, y el historial de IE es prácticamente una lista de sitios web que también ha visitado. No creo que hagan una distinción de los sitios que ha ingresado y escrito manualmente, en comparación con los bits que se recuperan automáticamente por la página HTML o su navegador (como a través de iframes, etc., y redirecciones automáticas, ventanas emergentes, etc.) ... así que me resulta difícil entender cuál es la distinción, y actualizaré este bit una vez que lo descubra.

  7. Anulando el agente de usuario predeterminado no está integrado correctamente, puede pasar su propio agente de usuario en el método de navegación, pero una vez que el usuario navega allí, el sitio obtendrá los detalles del agente de usuario de sus programas como se ha establecido Sin embargo, esto no se perpetuará. Entonces, una vez que el usuario sigue un enlace en la página navegada, el control WebBrowser continuará enviando el agente de usuario real (real) que el control WB está usando para renderizar su sitio, a menos que, por supuesto, intercepte la navegación, cancélela y vuelva a navegar usando el método .navigate nuevamente al enviar su propio agente de usuario (nuevamente). Esto no podrá dar cuenta de cosas como imágenes y archivos de etiquetas LINK, etc., ya que no obtendrá BeforeNavigate eventos para estos, por lo que no puede interceptarlos y modificar los encabezados enviados para ellos. En su lugar, debe utilizar una solución externa mediante la importación de algunas funciones externas urlmon.dll: esto puede hacerlo al 100% y funciona a la perfección, sin embargo, es otra dependencia añadida (pero urlmon.dll se incluye con todas las versiones de Windows relevantes hasta la fecha).

  8. No hay ninguna propiedad o método de "redirigir todas mis actividades de control de WB a este marco particular", aunque puede y tendrá que desarrollar eso si lo desea o necesita, el único soporte de marco es un argumento TargetFrameName que viene con el método .navigate, y tendrá que obtener una referencia y dirigir todo lo que haga allí manualmente, para cada acción que debe estar ocurriendo allí, ya que los usuarios pueden hacer clic en las cosas desde cualquier marco y no tendrían idea o pista a menos que lo compruebes.

  9. Seguridad de cuadros cruzados para sitios con marcos que apuntan a dominios externos: como usted sabrá, si tiene una página en abc.com y tiene un marco flotante que tiene una fuente de un dominio llamado xzy.com (como la mayoría de los anunciantes lo hacen cuando transmiten contenido desde sus propios servidores), se encontrará con problemas de seguridad de dominio entre cuadros si intenta acceder a ese marco, independientemente de los privilegios elevados con los que se ejecuta su aplicación. Es una tontería, y ni siquiera le informarán al respecto, en su lugar, su documento de referencia que apunta al marco simplemente no tendrá datos y no podrá usarlo y el control WB no le dirá por qué. Todo lo que tendrá acceso es la URL de origen del marco y eso es todo, nada dentro de él. ¿Solución? Bueno, hay un TypeLib registrable en su máquina que puede usar para anular esto, no integrado en el control WB, y ni siquiera incorporado en su propia interfaz de programación, de hecho es una rutina C externa que necesita usar al hacer referencia. y registrar el TypeLib (no estoy seguro de si hay una nueva forma de hacerlo sin este método en .NET ahora mismo días). Sin embargo, también necesitará escribir código alrededor de este TypeLib en su entorno de programación actual (código excesivo para usar el material en el registro TypeLib, así que no se trata solo de llamar a una función, sino de escribir más código alrededor de esa función que Estaré usando).

  10. Activar/desactivar JavaScript, activar/desactivar la configuración de navegación, como los sonidos de navegación, etc.Si está escribiendo un programa extractor web, los sonidos de navegación volverán locos a sus usuarios, activar o desactivar estas opciones no está integrado en el control WebBrowser, puede cambiar las cosas de manera global utilizando el registro si es necesario y luego cambiarlas de vuelta una vez hecho. Tendrá que buscar valores reg para cada una de estas configuraciones/opciones relacionadas con la configuración de Internet. Hay formas de hacer esto para su instancia de aplicación, importando rutinas desde InternetSecuritySettings, creo, pero una vez más, no integrado en WB, y solo otra serie de hacks para agregar a la lista.

  11. Por supuesto, deberá detectar si existe una conexión a Internet y si hay una disponible. El control WB ni siquiera te da un atisbo de esperanza al hacer esto, a pesar de que es una parte vital para que funcione. Por lo tanto, si no desea que las molestas ventanas emergentes de la conexión de acceso telefónico MS (para aquellos que usan acceso telefónico) o el asistente de Internet para aquellos en otras conexiones, aparezca CADA VEZ QUE SU CONTROL WB TRATE DE HACER UNA CONEXIÓN o intente navegar en algún lugar, entonces necesitarás usar un control para tratar de verificar las conexiones manualmente, y este control tendrá que ser un control externo a MS, y un control que no tiene la API de MS en su núcleo (ya que las API de Internet de MS son las API que activan estos cuadros emergentes para la conexión a Internet). Por lo tanto, deberá obtener un control de tipo winsocks externo escrito desde cero que no use winsocks, aprender a usarlo y usarlo para tratar de verificar si Internet está conectado antes de cada vez que realice una acción con el WB. controlar.

  12. Aparecerán muchos mensajes de "Error de automatización" o "Error no especificado", donde ni siquiera le dice qué salió mal, cuando se trata de elementos en un documento html/página en vivo, estos son generalmente cuando hay html que se realiza de una manera no recomendada, a pesar de que es una forma que un navegador puede tratar y leer, y trata de manera regular. Por ejemplo, si tiene un enlace Anchor con target = _top y no tiene comillas alrededor de la parte _top, aunque los navegadores entiendan esto y se comporten como se espera, el control del navegador web arrojará sus manos al aire y se dará por vencido, arrojando un "error no especificado", sin siquiera decirle de qué es tan exigente. Por lo tanto, deberá asegurarse de que el elemento esté escrito así: target = "_ top" para que el control de WB se comporte, y hacer estos cambios en cada documento en vivo puede ser tedioso, y necesitará escriba rutinas generales para hacer esto para cada página si lo necesita: rutinas que se ejecutan después de que el documento está cargado por completo (que deberá detectar de manera confiable para poder hacerlo). Si tuviera que elegir lo más difícil de hacer correctamente con el control WB, tendría que estar detectando cuándo la página está completa y se carga completamente, de manera confiable. Además de eso, es lo más importante que tendrá que hacer también, con el control de WB, ya que casi todo depende de la detección precisa de esto.

  13. Necesita un objeto de historia separado, porque si elige "sin historial" durante la navegación o encuentra una manera de hacer que la navegación sin historial funcione, puede estar seguro de que no funcionará ir o volver a estas páginas (es decir, llamando .GoBack o .GoForward a estas páginas y direcciones). Una vez que elimine del historial, o especifique que no se guardará ningún historial para esto o para una navegación particular, regresar allí es imposible a menos que vuelva a navegar a esa página. Deberían haber conservado una lista de historial en memoria que debería haber estado disponible para volver a ella aunque la página se haya eliminado del historial global (que es la única forma en que se realiza la búsqueda sin historial). Por lo tanto, si intenta regresar, obtendrá (además de todo) un error de tiempo de ejecución, y solo en los últimos días de .NET proporcionó un método llamado .CanGoBack para verificar si puede regresar o no, antes de esa fecha. (si usa pre.NET) debería tener que escribir el código al respecto o tratar de mantener el conteo de dónde estaba (lo cual no es fácil, pero sí factible).

puedo seguir adelante (creo), pero voy a dejarlo así por ahora, sin embargo, aparte de esas cosas, es un control muy bien y se abre la puerta a un nuevo mundo de aplicaciones e ideas que puedes hacer.Como he señalado en algunos de estos puntos, estos son todos los problemas que he resuelto (y todavía hay más, que he resuelto cuando se necesitaba una solución), así que si tiene alguna pregunta o necesita ayuda, deje que ya sé que estaría feliz de al menos tratar de ayudarte.

Cuando estaba tratando de entender esto, no había nadie para ayudarme, ya que nadie realmente sabía mucho sobre este control, así que tuve que resolverlo poco a poco, uno por uno. Desde entonces, ha ganado popularidad, y hay más personas que lo usan (especialmente desde que la versión .NET ha proporcionado mejoras incrementales). Por lo tanto, estaría encantado de ayudar a cualquiera que se encuentre en la situación en la que he estado antes, ya que recuerdo que era un lugar aterrador y solitario, y MS no hizo ninguna documentación sabia. Es solo algo que desarrollaron para uso interno y dejaron que otros lo usaran, mientras que proporcionaban solo una lista de argumentos/parámetros de entrada/salida & lista de valores de retorno para todas las propiedades, métodos y eventos, y eso era todo, sin significado ni contexto o ejemplos de código real asociados con él, seguramente, nada documental en cuanto a la resolución del conjunto de problemas que conlleva.

Ok, eso lo hace por ahora, estaría interesado en las opiniones de las personas sobre este control y uso de la misma, así que siéntase libre de dejar un comentario. Cuídate. Erx.

+2

Gracias por su gran respuesta. También tengo problemas para detectar cuándo se carga la página. ¿Podría darme más detalles? Lo he intentado de muchas maneras, pero todavía no puedo hacerlo funcionar correctamente –

+0

hola, estoy interesado en las soluciones que prometiste ayudar, por favor ayúdame con la información – Smith

+1

Hola chicos, estaré encantado de ayudarte, pero cada uno de estos cuestiones justifican una nueva pregunta, por lo que necesitaría hacer una nueva pregunta para cada una de sus preguntas, y luego señalarme para poder darle mis respuestas. –