如何从单个winforms应用程序进程以编程方式控制多个浏览器(aXWebBrowser控件),以同一个远程网站为目标,但每个浏览器与远程站点一起位于自己的会话范围内?
目标 - 构建一个自动使用网站的应用程序。目标是让应用程序完成最多5个用户与同一网站上的浏览器交互的工作。
明显的挑战 - 每个浏览器实例共享其远程网站发送给它的“会话”数据。结果是各种浏览器无法充当实际的多个人类用户。无论实例化多少个不同的aXWebBrowser控件,每个控件都会丢失其会话上下文,并共享由上一个/最新/最近实例化的浏览器建立的会话上下文。换句话说,最后一次启动的控制会破坏其前面任何控件的已建立会话上下文。
已经尝试过 - 将以下注册表项之一添加到'hkcu \ software \ microsoft \ internet explorer \ main':TabProcGrowth = DWORD:0,FrameMerging = DWORD:0,SessionMerging = DWORD:0。从我的桌面图标(应用程序外部)启动IE8时,这可以正常工作,IE8可以按照需要运行。但是,在运行应用程序时,使用axWewbBrowser控件,它确实有效,注册表设置似乎对axWebBrowser控件没有影响。在应用程序外部查看令人厌恶的行为的其他方法包括:在IE8文件菜单中单击“新建会话”,然后使用-nomerge启动iexplore.exe。这些在应用程序中不起作用,因为axWebBrowser控件使用Wininet进行通信。
约束 - 已经编写了大量代码并使用aXWebBrowser控件(Internet Explorer ActiveX自动化Web浏览器)工作,因此理想的解决方案不需要使用新控件重写代码。 - 找到解决方案后,应用程序将浏览器窗口显示给工作站用户。 - winforms应用程序(.NET 2.0)托管控件 - 浏览器都针对同一个远程网站。
答案 0 :(得分:0)
据我所知,只要每个浏览器都加载到同一个线程上,IE就会将它们视为同一个会话。
我通过为每个会话创建一个新线程和一个新窗口解决了这个问题。
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; }
}