2009-06-02 22 views
40

Estoy intentando cambiar el UserAgent del control WebBrowser en una aplicación Winforms.Cambiar el agente de usuario del control WebBrowser

que han logrado con éxito esto usando el siguiente código:

[DllImport("urlmon.dll", CharSet = CharSet.Ansi)] 
private static extern int UrlMkSetSessionOption(
    int dwOption, string pBuffer, int dwBufferLength, int dwReserved); 

const int URLMON_OPTION_USERAGENT = 0x10000001; 

public void ChangeUserAgent() 
{ 
    List<string> userAgent = new List<string>(); 
    string ua = "Googlebot/2.1 (+http://www.google.com/bot.html)"; 

    UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, ua, ua.Length, 0); 
} 

El único problema es que esto sólo funciona una vez. Cuando intento ejecutar el método ChangeUserAgent() por segunda vez, no funciona. Permanece configurado al primer valor modificado. Esto es bastante molesto y lo he intentado todo, pero simplemente no cambiará más de una vez.

¿Alguien conoce un enfoque diferente y más flexible?

Gracias

+1

He intentado el método anterior, pero no funcionó para WPF (System.Windows.Controls.WebBrowser) –

Respuesta

32

no estoy seguro de si yo sólo debería copiar/pegar desde un website, pero prefiero dejar la respuesta en este caso, en lugar de un enlace. Si alguien puede aclarar en los comentarios, estaré muy agradecido.

Básicamente, debe extender la clase WebBrowser.

public class ExtendedWebBrowser : WebBrowser 
{ 
    bool renavigating = false; 

    public string UserAgent { get; set; } 

    public ExtendedWebBrowser() 
    { 
     DocumentCompleted += SetupBrowser; 

     //this will cause SetupBrowser to run (we need a document object) 
     Navigate("about:blank"); 
    } 

    void SetupBrowser(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 
     DocumentCompleted -= SetupBrowser; 
     SHDocVw.WebBrowser xBrowser = (SHDocVw.WebBrowser)ActiveXInstance; 
     xBrowser.BeforeNavigate2 += BeforeNavigate; 
     DocumentCompleted += PageLoaded; 
    } 

    void PageLoaded(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 

    } 

    void BeforeNavigate(object pDisp, ref object url, ref object flags, ref object targetFrameName, 
     ref object postData, ref object headers, ref bool cancel) 
    { 
     if (!string.IsNullOrEmpty(UserAgent)) 
     { 
      if (!renavigating) 
      { 
       headers += string.Format("User-Agent: {0}\r\n", UserAgent); 
       renavigating = true; 
       cancel = true; 
       Navigate((string)url, (string)targetFrameName, (byte[])postData, (string)headers); 
      } 
      else 
      { 
       renavigating = false; 
      } 
     } 
    } 
} 

Nota: Para utilizar el método anterior, deberá agregar una referencia COM a "Microsoft Internet Control".

También menciona su enfoque y afirma que el control WebBrowser parece almacenar en caché esta cadena de agente de usuario, por lo que no cambiará el agente de usuario sin reiniciar el proceso.

+0

¿Hay alguna manera de reiniciar el proceso, tal vez mediante el uso de subprocesos? Tengo una experiencia limitada con winforms. – Proximo

+0

No estoy tan seguro, lo probaría yo mismo, pero creo que el enfoque que di en mi respuesta debería funcionar. Sin embargo, es menos elegante. También me pregunto si podrías eliminar el control y crear uno nuevo en tiempo de ejecución, pero supongo que puede ser un poco caro. –

+0

De hecho, agregué esa clase a mi proyecto y no funcionó en absoluto. Así que ahora creo que tengo que intentar reiniciar el enfoque del proceso. – Proximo

58

La forma más sencilla:

webBrowser.Navigate("http://localhost/run.php", null, null, 
        "User-Agent: Here Put The User Agent"); 
+3

debe terminar el encabezado personalizado con '\ r \ n' – Smith

+8

Si el control del navegador web se aleja de ese URI (al hacer clic en un enlace, o retroceder/avanzar), el agente de usuario se restablece. Idealmente, la solución debería funcionar para todas las solicitudes que haga el control. – monzonj

+5

Solo funciona para la solicitud original pasada a Navigate: todas las llamadas AJAX dentro del sitio web seguirán usando el UA predeterminado –

13

Además, hay una opción de actualización en la función (de acuerdo con MSDN). Me funcionó bien (debe configurarlo antes de que cambie cualquier agente de usuario). Entonces el código de la pregunta podría cambiarse así:

[DllImport("urlmon.dll", CharSet = CharSet.Ansi)] 
private static extern int UrlMkSetSessionOption(
    int dwOption, string pBuffer, int dwBufferLength, int dwReserved); 

const int URLMON_OPTION_USERAGENT = 0x10000001; 
const int URLMON_OPTION_USERAGENT_REFRESH = 0x10000002; 

public void ChangeUserAgent() 
{ 
    string ua = "Googlebot/2.1 (+http://www.google.com/bot.html)"; 

    UrlMkSetSessionOption(URLMON_OPTION_USERAGENT_REFRESH, null, 0, 0); 
    UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, ua, ua.Length, 0); 
} 
+1

del control ¿por qué no está usando la variable 'userAgent'? – Sebastian

+0

Ha sido extraído de mi propio código, no debería estar allí. Tks por señalarlo. – natenho

+1

La respuesta aceptada no funcionará si usted, por ejemplo, inicia sesión en Facebook y necesita obtener la aprobación de permisos del usuario ("renavigate" causa problemas). Así que cree su navegador integrado y use URLMON_OPTION_USERAGENT_REFRESH luego URLMON_OPTION_USERAGENT para configurar su UA personalizado. Como se indicó anteriormente, repita según sea necesario o solo configure URLMON_OPTION_USERAGENT_REFRESH para volver al IE de IE predeterminado. –

2

Me gustaría agregar a la respuesta de @Jean Azzopardi.

void BeforeNavigate(object pDisp, ref object url, ref object flags, ref object targetFrameName, 
     ref object postData, ref object headers, ref bool cancel) 
{ 
    // This alone is sufficient, because headers is a "Ref" parameters, and the browser seems to pick this back up. 
    headers += string.Format("User-Agent: {0}\r\n", UserAgent); 
} 

Esta solución funcionó mejor para mí. Utilizar el renavigating me causó otros problemas extraños, como el contenido del navegador que de repente se desvanece y, a veces, sigue recibiendo el navegador no compatible. Con esta técnica, todas las solicitudes en Fiddler tenían el agente de usuario correcto.

Cuestiones relacionadas