2009-06-02 2 views
40

Я пытаюсь изменить UserAgent элемента управления WebBrowser в приложении Winforms.Изменение пользовательского агента элемента управления WebBrowser

Я успешно добились этого, используя следующий код:

[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); 
} 

Единственная проблема заключается в том, что это работает только один раз. Когда я пытаюсь запустить метод ChangeUserAgent() во второй раз, он не работает. Он остается установленным для первого измененного значения. Это очень раздражает, и я пробовал все, но он просто не изменится более одного раза.

Кто-нибудь знает о другом, более гибком подходе?

Благодаря

+1

Я пробовал метод выше, но он не работал для WPF (System.Windows.Controls.WebBrowser) –

ответ

32

Я не уверен, должен ли я просто скопировать/вставить из website, но я предпочел бы оставить ответ здесь, вместо ссылки. Если кто-нибудь может прояснить в комментариях, я буду очень обязан.

В принципе, вам необходимо расширить класс 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; 
      } 
     } 
    } 
} 

Примечание: для использования вышеуказанного метода вам необходимо добавить ссылку на COM на «Microsoft Internet Controls».

Он также упоминает ваш подход и утверждает, что элемент управления WebBrowser, похоже, кэширует эту строку пользовательского агента, поэтому он не будет изменять агент пользователя без перезапуска процесса.

+0

Есть ли способ перезапустить процесс, возможно, используя потоки? У меня ограниченный опыт работы с winforms. – Proximo

+0

Я не уверен, я бы попробовал сам, но я думаю, что подход, который я дал в своем ответе, должен работать. Однако он менее изящный. Я также задаюсь вопросом, можно ли удалить элемент управления и создать новый во время выполнения, но я думаю, что это может быть немного дорого. –

+0

Я действительно добавил этот класс к моему проекту, и он вообще не работал. Так что теперь я думаю, что мне нужно попробовать перезапустить процессный подход. – Proximo

58

Самый простой способ:

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

вы должны закрыть пользовательский заголовок с помощью '\ r \ n' – Smith

+8

Если элемент управления веб-браузером удаляется от этого URI (при нажатии ссылки или перемещении назад/вперед) пользовательский агент сбрасывается. В идеале это решение должно работать для всех запросов, которые выполняет контроль. – monzonj

+5

Он работает только для первоначального запроса, переданного на навигацию. Все вызовы AJAX внутри веб-сайта будут по-прежнему использовать значение по умолчанию UA –

13

Кроме того, есть опция обновления в функции (в соответствии с MSDN). Он работал хорошо для меня (вы должны установить его перед изменением любого пользовательского агента). Тогда код вопроса можно было бы изменить следующим образом:

[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

. Почему вы не используете переменную 'userAgent'? – Sebastian

+0

Это было извлечено из моего собственного кода, не должно быть. Tks для указания этого. – natenho

+1

Принятый ответ не будет работать, если вы, например, заходите в Facebook и должны получить разрешение от пользователя («renavigate» вызывает проблемы). Поэтому создайте свой встроенный браузер и используйте URLMON_OPTION_USERAGENT_REFRESH, а затем URLMON_OPTION_USERAGENT, чтобы установить свой пользовательский UA. Как указано выше, повторите по мере необходимости или установите URLMON_OPTION_USERAGENT_REFRESH для возврата к IEU по умолчанию. – 2014-04-23 16:28:33

2

Я хотел бы добавить к ответу @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); 
} 

Это решение наилучшим образом подходит для меня. Использование renavigating вызвало другие странные проблемы для меня, такие как содержимое браузера, внезапно исчезающее, а иногда и получение Unsupported Browser. С помощью этой техники все запросы в Fiddler имели правильный User Agent.

Смежные вопросы