Skip to main content
 首页 » 编程设计

c#之在 WinForms 应用程序中使用 aXWebBrowser 控件分离 session

2024年01月13日27bhlsheji

如何从单个 winforms 应用程序进程以编程方式控制多个浏览器(aXWebBrowser 控件),目标是同一个远程网站,但每个浏览器都在自己与远程站点的 session 范围内?

目标 - 构建一个自动使用网站的应用程序。目标是让应用程序完成最多 5 个用户在同一网站上与浏览器交互的工作。

明显的挑战 - 每个浏览器实例共享远程网站发送给它的“ session ”数据。结果是各种浏览器无法像实际的多个人类用户那样工作。无论实例化了多少个不同的 aXWebBrowser 控件,每个控件都会丢失其 session 上下文,并共享由最后一个/最新/最近实例化的浏览器建立的 session 上下文。换句话说,最后启动的控件会破坏它之前的任何控件已建立的 session 上下文。

已经尝试过 - 将以下注册表项之一添加到“hkcu\software\microsoft\internet explorer\main”:TabProcGrowth=DWORD:0、FrameMerging=DWORD:0、SessionMerging=DWORD:0。当从我的桌面图标(应用程序外部)启动 IE8 时,这工作正常,IE8 的行为符合预期。但是,在运行应用程序时,使用 axWewbBrowser 控件,它确实有效,注册表设置似乎对 axWebBrowser 控件没有影响。在应用程序外部查看不良行为的其他方法包括:单击 IE8 文件菜单中的“新建 session ”,并使用 -nomerge 启动 iexplore.exe。这些在应用程序中不起作用,因为 axWebBrowser 控件使用 Wininet 进行通信。

约束 - 已经使用 aXWebBrowser 控件(Internet Explorer ActiveX 可自动化 Web 浏览器)编写并运行了大量代码,因此理想的解决方案不需要使用新控件重新编写代码。 - 找到解决方案后,应用程序会将浏览器窗口显示给工作站用户。 - winforms 应用程序 (.NET 2.0) 正在托管控件 - 浏览器都针对同一个远程网站。

请您参考如下方法:

据我所知,只要每个浏览器都在同一个线程上加载,IE 就会始终将它们视为同一个 session 。

我通过为每个 session 创建一个新线程和一个新窗口来解决这个问题。

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    private static void Main() 
    { 
        Application.EnableVisualStyles(); 
        Application.SetCompatibleTextRenderingDefault(false); 
 
        //// How many test windows do we need to create. 
        int numberOfClients = 5; 
        System.Threading.Thread[] threads =  
            new System.Threading.Thread[numberOfClients]; 
 
        //// Create threads for each of the windows, and then start them. 
        for (int i = 0; i < numberOfClients; i++) 
        { 
            threads[i] = new System.Threading.Thread(Program.StartTest); 
            threads[i].SetApartmentState(System.Threading.ApartmentState.STA); 
            //// Passing in the startup parameters for each each instance. 
            threads[i].Start(new StartupParameters(i)); 
        } 
 
        //// This will keep the application running until  
        ////  all the windows are closed. 
        foreach (System.Threading.Thread thread in threads) 
        { 
            thread.Join(); 
        } 
    } 
 
    /// <summary> 
    /// Starts the test form. 
    /// </summary> 
    /// <param name="state"> 
    /// The state object containing our startup parameters. 
    /// </param> 
    private static void StartTest(object state) 
    { 
        StartupParameters parameters = state as StartupParameters; 
        YourTestForm yourTestForm = new YourTestForm(); 
 
        //// Set the needed parameters before we run the form.   
        //// Add your parameters here. 
        yourTestForm.Text = string.Format("Test form {0}", parameters.Index); 
 
        //// Run the test. 
        Application.Run(yourTestForm); 
    } 
} 
 
/// <summary> 
/// Contains the startup parameters used to configure  
/// each new instance of the test form. 
/// </summary> 
public class StartupParameters 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="StartupPramitures"/> class. 
    /// </summary> 
    /// <param name="index">The index.</param> 
    public StartupParameters(int index) 
    { 
        this.Index = index; 
    } 
 
    /// <summary> 
    /// The index for this test form. 
    /// </summary> 
    public int Index { get; private set; } 
}