nuits.jp blog

C#, Xamarin, WPFを中心に書いています。Microsoft MVP for Development Technologies。

WPFのWebBrowserでUserAgentを偽装する

WPFで作ったアプリケーション内にWebBrowserを埋め込んで、そのWebBrowserで任意のUserAgentを利用する方法を記載します。
解決すれば何てことは無かったのですが、案外ハマったのでメモを残しておきます。

解決方法

ハマった点はさておき、先に解決策を記載します。
urlmon.dllのUrlMkSetSessionOption関数を利用する方法が最も簡単で正しく動作します。

WebBrowserの置かれているWindow(やUserContorolなど)のInitializeComponent以降で以下のように一度呼び出します。
ここではWindowのコンストラクタの中から呼び出しています。

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

        public MainWindow()
        {
            InitializeComponent();
            var userAgent = "hoge";
            UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, userAgent, userAgent.Length, 0);
        }

これでUserAgentが「hoge」に置き換えられます。
Githubに、実際に動くコードと、テスト用にクライアントのUserAgentを表示するWebFormsのコードを置いておきましたので良かったら参考にしてください。

github.com

ハマった箇所

案外ハマって苦労したので、ハマった箇所も一緒に残しておきます。
最初は、WebBrowserのNavigatingイベントをハンドルして、UserAgentを偽装した形でNavigateメソッドを呼び出し直そうとしたのですが、POST時の振る舞いなんかでちょっとハマりました。
そもそもPOSTデータをどっから取ってくるのかで、だいぶ悩まされましたし、取ってきて設定して呼び出したらASP.net側でViewStateのBase64エンコードが不正だと怒られるし。。。
結局、解決できなかったのですが、上の方法で回避することにしました。

そもそも、なんでUA偽装とかしないといけないのか。。。顧客の要求なんで仕方ないんですけど、面倒でした。