2011-08-26 64 views
2

我有一个我正在尝试与远程桌面集成的公司的帮助台软件包。我希望实现的功能之一是,如果远程桌面连接当前可用于所选系统,则可以确定(当您浏览客户端列表时)。我正在使用的库是“微软终端服务控制” - (AxInterop.MSTSCLib AxMsRdpClient7)在多个线程上运行COM组件控件

现在我的问题是,我想要在单独的线程上执行此任务(尝试连接),以防止阻止UI(给定我可能会同时尝试在众多客户端建立连接),并且迄今为止一直不成功。

下面是代码的想法......

public void AttemptLogin(string password) 
{ 
    this._thread = new Thread(LoginAttempt); 
    this._thread.SetApartmentState(ApartmentState.STA); 
    this._thread.Start(password); 
} 


protected void LoginAttempt(object password) 
{ 
    AxMsRdpClient7 remoteDesktop = new AxMsRdpClient7(); 
    remoteDesktop.CreateControl(); 

    remoteDesktop.UserName = this._username; 
    remoteDesktop.Server = this._server; 
    WireEventHandlers(remoteDesktop); 
    IMsTscNonScriptable passwordContainer = (IMsTscNonScriptable)remoteDesktop.GetOcx(); 
    passwordContainer.ClearTextPassword = password.ToString(); 
    remoteDesktop.Connect(); 
} 

基本上上面的代码完美地工作,如果我在UI线程中执行它和控件添加到窗体集合,但是当我尝试运行这在一个单独的线程上显示,根本不会发生任何操作。连接()上不会引发异常。没有事件发生,似乎没有任何反应。

我想我所希望的是确认我正在尝试做什么(在线程中运行COM组件)IS INFACT POSSIBLE和任何有关可能需要执行此步骤所需的步骤的进一步指导将非常高赞赏。

+0

您可能想要阅读以下问题:http://stackoverflow.com/questions/804968/how-can-a-background-thread -hang最UI线程。在我的情况下,我创建并在计时器线程中运行ActiveX控件。 –

+0

您违反了STA线程的硬性要求:它们必须抽取消息循环。它用于编组调用,但COM组件经常在内部使用它来处理同步。 –

回答

3

好消息是,你正在尝试做的事情是可能的。由于您正在创建COM对象并在同一个线程中使用它,因此不需要担心任何编组问题。 (如果开始将COM接口指针传递给另一个线程,则创建该对象的STA线程将不得不使用消息泵。)

我没有使用MSTSC控件,但我的猜测是它可能需要即使它是一个隐藏的窗口,它仍然可以在窗口之前被托管。我会创建一个新的表单(在你的后台STA线程上),看看是否有帮助。然后,您可以尝试隐藏表单,直到需要显示终端服务客户端。如果您不确定如何在多个线程中使用多个表单,请参阅Multiple Windows, Multiple Threads

+0

吮吸它在一个窗口托管是必需的,但似乎是修复...干杯 –