WebBrowser コントロールのユーザー エージェントの変更
-
06-09-2019 - |
質問
Winforms アプリケーションの WebBrowser コントロールの UserAgent を変更しようとしています。
次のコードを使用してこれを正常に達成しました。
[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 回目に実行しようとすると、機能しません。最初に変更された値に設定されたままになります。これは非常に面倒で、あらゆることを試しましたが、何度かしか変わりません。
別の、より柔軟なアプローチを知っている人はいますか?
ありがとう
解決
からコピー&ペーストするだけでよいのかわかりません。 Webサイト, 、しかし、リンクの代わりにここに答えを残したいと思います。誰かがコメントで明確にしてくれるなら、私は大いに感謝します。
基本的には、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 Internet Controls」への COM 参照を追加する必要があります。
彼はあなたのアプローチにも言及し、WebBrowser コントロールがこのユーザー エージェント文字列をキャッシュしているようで、プロセスを再起動しない限りユーザー エージェントを変更しないと述べています。
他のヒント
最も簡単な方法:
webBrowser.Navigate("http://localhost/run.php", null, null,
"User-Agent: Here Put The User Agent");
また、リフレッシュオプションはに従って(関数であります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);
}
私は@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を使用すると、ブラウザコンテンツが突然消失、そして時には、まだサポートされていないブラウザを得るようなもの、私のために他の奇妙な問題を引き起こしました。この技術では、フィドラーのすべての要求が正しいユーザエージェントを持っています。