UWP - 調整 WebView 的 UserAgent

想要在 UWP 調整 WebView 的 User-Agent 記得先把 App 的 mini SDK version 升級到在 Windows 10 (15063),來看一下是怎麽做的吧。

我參考 Set the UserAgent for a UWP WebView 的介紹,得知可以從 Win32 API 的 urlmon.dll 做到這個效果。

如下程式碼:

const int URLMON_OPTION_USERAGENT = 0x10000001;

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

[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkGetSessionOption(int dwOption, StringBuilder pBuffer, int dwBufferLength, ref int pdwBufferLength, int dwReserved);

因此,我就好奇 urlmon.dll 還可以做到那些用途,是否還有其他 Win32 API 可以使用。 根據 APIs from urlmon.dll 的説明提到:

API Requirements
CreateUri Introduced into urlmon.dll in 10.0.10240. Moved into ext-ms-win-core-iuri-l1-1-0.dll in 10.0.15063.
CreateUriWithFragment Introduced into urlmon.dll in 10.0.10240. Moved into ext-ms-win-core-iuri-l1-1-0.dll in 10.0.15063.
UrlMkGetSessionOption Introduced into urlmon.dll in 10.0.15063.
UrlMkSetSessionOption Introduced into urlmon.dll in 10.0.15063.

需要 15063 以上才有支援,而 UrlMkSetSessionOption 調整 UserAgent 的參數值為 0x10000001,參考如下:

Flag Value Description
URLMON_OPTION_USERAGENT 0x10000001 Sets the user agent string for this process.
URLMON_OPTION_USERAGENT_REFRESH 0x10000002 Refreshes the user agent string from the registry for this process.

需注意,利用 UrlMkSetSessionOption 的 (0x10000001) 更新 UserAgent 之後,在 App 執行期間是用的 WebView 都是使用修改後的值。

利用下面的程式片段可設定與取得目前的 UserAgent:

public static class UserAgent
{
    const int URLMON_OPTION_USERAGENT = 0x10000001;

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

    [DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
    private static extern int UrlMkGetSessionOption(int dwOption, StringBuilder pBuffer, int dwBufferLength, ref int pdwBufferLength, int dwReserved);

    public static string GetUserAgent()
    {
        // 設定讀取的長度 255 bytes ,因爲是 0x (16 進位數)
        int bufferLength = 255;
        StringBuilder buffer = new StringBuilder(bufferLength);
        int length = 0;
        UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, buffer, bufferLength, ref length, 0);
        return buffer.ToString();
    }

    public static void SetUserAgent(string agent)
    {
        // S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED, and E_FAIL
        var hr = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, agent, agent.Length, 0);
		
        // 轉換得到的值看是否為 Exception
        var ex = Marshal.GetExceptionForHR(hr);
		
        if(ex!= null)
        {
            throw ex;
        }
    }

    public static void AppendUserAgent(string appendContent)
    {
        SetUserAgent(GetUserAgent() + appendContent);
    }
}

另外有看過這篇 Setting a custom User-Agent in the UWP WebView control 的介紹,

還可以使用 WebView.NavigateWithHttpRequestMessage 時,

另外建立一個 HttpRequestMessage 調整送出的 UserAgent,但是非常複雜。

 

======

如果您是使用 HttpClient 要調整 UserAgent 是很容易的,但是 WebView 是 UWP 包裝好的要調整就比較麻煩。

因此整理上面的介紹與使用方式,希望有幫助到大家。

 

References: