C# 更改WebBrowser控件的用户代理

C# 更改WebBrowser控件的用户代理,c#,winforms,webbrowser-control,user-agent,C#,Winforms,Webbrowser Control,User Agent,我试图在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_

我试图在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);
}
[DllImport(“urlmon.dll”,CharSet=CharSet.Ansi)]
私有静态外部int UrlMkSetSessionOption(
int dwOption、字符串pBuffer、int dwBufferLength、int dwReserved);
const int URLMON_OPTION_USERAGENT=0x10000001;
public void ChangeUserAgent()
{
List userAgent=new List();
string ua=“谷歌机器人/2.1(+http://www.google.com/bot.html)";
UrlMkSetSessionOption(URLMON_OPTION_USERAGENT,ua,ua.Length,0);
}
唯一的问题是,这只起作用一次。当我第二次尝试运行ChangeUserAgent()方法时,它不起作用。它保持设置为第一个更改的值。这很烦人,我什么都试过了,但改变不了一次

有人知道一种不同的、更灵活的方法吗


谢谢

我不确定是否应该从a复制/粘贴,但我宁愿把答案留在这里,而不是一个链接。如果有人能在评论中澄清,我将不胜感激

基本上,您必须扩展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控件”

他还提到了您的方法,并指出WebBrowser控件似乎缓存了此用户代理字符串,因此它不会在不重新启动进程的情况下更改用户代理。

最简单的方法:

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

此外,函数中还有一个刷新选项(根据)。它对我来说很好(您应该在任何用户代理更改之前设置它)。然后问题代码可以更改如下:

[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会给我带来其他奇怪的问题,比如浏览器内容突然消失,有时还会出现不受支持的浏览器。使用此技术,Fiddler中的所有请求都有正确的用户代理。

我尝试了上述方法,但对WPF(System.Windows.Controls.WebBrowser)链接无效。所以,是的,将近两年后,复制和粘贴被证明是正确的做法:)@zourtney,呵呵,终于有了回报!还有办法吗?显然,WebBrowser的WPF变体是密封的,不能以这种方式使用。如果控件托管在.net应用程序中,BeforeNavigate2不会触发这是什么
SHDocVw.WebBrowser xBrowser=(SHDocVw.WebBrowser)ActiveXistance
?如果webbrowser控件导航到该URI之外(单击链接或前后移动时),用户代理被重置,则必须使用
\r\n
终止自定义标头。理想情况下,该解决方案应该适用于控件执行的所有请求。它只适用于传递给导航的原始请求-网站中的所有AJAX调用仍将使用控件的默认值UA@Constantin当我在项目中使用此代码时,Webbrowser将自动打开带有url的默认浏览器。我只想将网页加载到webbrowser,但打开额外的浏览器。我的代码中遗漏了什么吗?
browser.Navigate(url,“用户代理:Mozilla/5.0(Linux;Android 6.0;Nexus 5 Build/MRA58N)AppleWebKit/537.36(KHTML,比如Gecko)Chrome/74.0.3729.157 Mobile Safari/537.36”)
为什么不使用
userAgent
变量?它是从我自己的代码中提取的,不应该存在。Tks指出这一点。例如,如果您登录Facebook并需要获得用户的权限批准(“renavigate”会导致问题),那么接受的答案将不起作用。因此,创建嵌入式浏览器并使用URLMON\u OPTION\u USERAGENT\u REFRESH,然后使用URLMON\u OPTION\u USERAGENT设置自定义UA。如上所述,根据需要重复或仅设置URLMON_选项_USERAGENT_REFRESH以返回默认IE UA。回顾过去,我必须说我喜欢这个答案,可惜已经晚了4年:)只是一个注释,如果使用表单,请在InitializeComponent()之前运行;