Question

I'm experimenting with Watin in Visual Studio 2012 (C#), but I cannot seem to get anything to work. Currently I have two text boxes in an aspx page (txtbox1 and txtbox2). I am trying to have Watin automatically input numbers into these two text boxes and then click on the "Calculate" button which will add the two numbers together. I installed the Watin framework and added the Watin.Core dll as a reference. Here is my code for so far in my .aspx page:

using WatiN.Core;

[STAThread]  
protected void Page_Load(object sender, EventArgs e)
{
    IE ie = new IE("http://localhost:5243/Addition.aspx");

    ie.TextField(Find.ByName("txtbox1")).TypeText("1");
    ie.TextField(Find.ByName("txtbox2")).TypeText("2");
    ie.Button(Find.ByValue("Calculate")).Click();
}

I keep getting the error message stating:"The CurrentThread needs to have it's ApartmentState set to ApartmentState.STA to be able to automate Internet Explorer". Do you know what can cause this? Thanks for any help in advance!

Was it helpful?

Solution

First of all, you're trying to automate Internet Explorer from the server-side ASP.NET code. This is generally a bad idea. This article describes the implications of doing this with Office, the same concerns apply to Internet Explorer.

That said, to succeed with what you're trying to do, you'd need to run an STA thread on the server side, and run your Watin code inside that thread. Placing [STAThread] on your ASP.NET Page_Load handler won't automagically make this happen.

Here is how it can be done, but again, doing so on the server is not recommended:

protected void Page_Load(object sender, EventArgs e)
{
    RunOnStaThread<object>(() =>
    {
        IE ie = new IE("http://localhost:5243/Addition.aspx");

        ie.TextField(Find.ByName("txtbox1")).TypeText("1");
        ie.TextField(Find.ByName("txtbox2")).TypeText("2");
        ie.Button(Find.ByValue("Calculate")).Click();

        return null;
    });
}

static T RunOnStaThread<T>(Func<T> func)
{
    var tcs = new TaskCompletionSource<T>();

    var thread = new Thread(() => 
    {
        try
        {
            tcs.SetResult(func());
        }
        catch (Exception ex)
        {
            tcs.SetException(ex);
        }
    });

    thread.IsBackground = true;
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();

    try 
    {
        return tcs.Task.Result;
    }
    finally
    {
        thread.Join();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top