在SSIS脚本组件上看 - 单线程公寓

时间:2011-03-31 16:22:54

标签: ssis watin sql-server-2008-r2

您好我需要从具有表单身份验证的站点下载文件,并使用Integration Services进一步处理文本文件。

对于文件下载,我选择使用WATIN,因此我导入了Watin库并编写了浏览器步骤脚本。但是,当我尝试运行代码时,我收到了此消息的异常。

  

CurrentThread需要拥有它   ApartmentState设置为   ApartmentState.STA能够   自动化Internet Explorer。

所有这一切都使用了 (使用method属性)

如果我尝试使用这行代码将其设置为STA

System.Threading.Thread.CurrentThread.SetApartmentState(Threading.ApartmentState.STA)

我得到了这个例外

  

错误:   System.Reflection.TargetInvocationException:   例外已被抛出   调用的目标。 --->   System.InvalidOperationException:   无法设置指定的COM   公寓州。在   System.Threading.Thread.SetApartmentState(的ApartmentState   状态)

如何更改SSIS脚本任务以使用此单线程公寓?

2 个答案:

答案 0 :(得分:2)

我通过使用STA ApartmentState创建另一个Thread来解决这个问题。

代码是这样的:

Private threadDelegate As ParameterizedThreadStart
Private filesdir As String

<STAThread()> _
Public Sub Main()
    Try
        threadDelegate = New ParameterizedThreadStart(AddressOf Me.DoSomething)
        StartBrowserRoutine(threadDelegate)
        Dts.TaskResult = ScriptResults.Success
    Catch
        Dts.TaskResult = ScriptResults.Failure
    End Try
End Sub

Private Sub StartBrowserRoutine(ByVal threadRoutine As ParameterizedThreadStart)
    Dim dialogThread As Thread = New Thread(threadRoutine)
    dialogThread.TrySetApartmentState(ApartmentState.STA)
    dialogThread.Start(Nothing)
    dialogThread.Join(System.Threading.Timeout.Infinite)
End Sub

Private Sub DoSomething()
    'Do Something
End Sub

希望这可以帮助有同样问题的人。

答案 1 :(得分:1)

我发现你的解决方案对我的情况非常有用,我添加了我用过的C#代码,以防有人需要它

public void Main() {
    Thread thread = new Thread(new ParameterizedThreadStart(DoMethod));
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join(); // wait for thread to end

    Dts.TaskResult = (int)ScriptResults.Success;
}

public void DoMethod(object sender) {
    System.Windows.Forms.Application.Run(new BrowserWindow("http://x.xxx"));
}

这是BrowserWindow

class BrowserWindow : Form
{
    private string url;

    public BrowserWindow(string url) {
        this.url = url;
        ShowInTaskbar = false;
        WindowState = FormWindowState.Minimized;
        Load += new EventHandler(Window_Load);
    }

    void Window_Load(object sender, EventArgs e) {
        WebBrowser wb = new WebBrowser();
        wb.AllowNavigation = true;
        wb.DocumentCompleted += wb_DocumentCompleted;
        wb.Navigate(this.url);
    }

    void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser web = sender as WebBrowser;
        // here goes the business logic
    }
}