2009-06-02 21 views
40

WinformsアプリケーションでWebBrowserコントロールのUserAgentを変更しようとしています。 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()メソッドを2回目に実行しようとすると機能しません。最初に変更された値に設定されたままです。これはかなり迷惑で、私はすべてを試しましたが、それは何度も変わることはありません。

誰かが違う、より柔軟なアプローチを知っていますか?

おかげ

+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; 
      } 
     } 
    } 
} 

注:上記の方法を使用するには、「Microsoftインターネットコントロール」へのCOM参照を追加する必要があります。

彼はあなたのアプローチについても言及し、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

WebブラウザコントロールがそのURIから移動すると(リンクをクリックするか、前後に移動するとき)、ユーザーエージェントはリセットされます。理想的には、コントロールが行うすべての要求に対してソリューションが機能するはずです。 – monzonj

+5

これは、Navigateに渡された元のリクエストに対してのみ機能します。ウェブサイト内のすべての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を設定してデフォルトのIE UAに戻ります。 –

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

この解決策は私には最適です。私は、ブラウザのコンテンツが突然消えてしまったり、サポートされていないブラウザが残っているような気がしていました。この手法では、Fiddlerのすべての要求が正しいユーザーエージェントを持っていました。

関連する問題