C# – Keep alive code fails with new RDP client


For our Secure Terminal Server project, we have a need to keep the RDP session open, that is, to prevent the remote computer from timing out and locking the session. A little background:

We have several virtual servers configured as go-between agents, with a client piece that launches a RDP session to the virtual servers, and starts an application there. That application reads connection data from a database, including the username and password for connecting on to the final destination computer.

For remote desktop sessions, we use the ActiveX control extracted from MSTSCAX.DLL (using AxImp). Because the user does not have access to the password for the remote machine, we absolutely must keep the session from timing out.

For the past several months, we have been using the following code, triggered by a Timer object, to accomplish this. That worked great, until I had to upgrade the RDP client to version 6 in order to access Server 2008 boxes (we were using version 4 or 5, not sure which). Since then, the call to SendKeys will sometimes throw an HRESULT E_FAIL error — often enough to cause major problems.

Does anyone have an idea as to what may be causing this? Better yet, does anyone have a better way to accomplish this that may work with the newer RDP client?


        _mstscKeyControl = (IMsRdpClientNonScriptable)_mstsc.GetOcx();

    private void KeepAlive()
            if ( null != _mstsc && 0 != _mstsc.Connected )
                bool[] bKeyUp = new bool[ 20 ];
                int[] KeyData = new int[ 20 ];            // value matches lParam parameter of WM_DOWN message

                 * Send CAPS LOCK on followed by OFF 
                 * The SendKeys routine will not allow remote data in a single call to be mixed with
                 * local data so this shouldn't mess up anything.

                KeyData[ 0 ] = (int)MapVirtualKey( 14, 0 );    // vk_capital = CAPS LOCK
                bKeyUp[ 0 ] = false;
                KeyData[ 1 ] = KeyData[ 0 ];
                bKeyUp[ 1 ] = true;

                _mstscKeyControl.SendKeys( 2, ref bKeyUp[ 0 ], ref KeyData[ 0 ] );
        catch ( Exception ex )
            MessageBox.Show( ex.Message + Environment.NewLine + ex.StackTrace );

Best Solution

Instead of a sendkeys, is there a way to pass some kind of mousemove instead? I suspect this would be less invasive, if you only move the mouse a few pixels. I'm not sure if RDP has some kind of mouse movement threshold, though - maybe a few pixels isn't enough for it to reset the disconnect/lock timeout.

We'll eventually have this same problem (our terminal server is currently 2003, but we'll upgrade to 2008 at some point), so I'd really be interested to know what your solution ends up being.