6

Got a small problem.

We have a internet-facing VPN from Netgear, to allow staff and teachers to access the school network using RDC from their home.

They login to the VPN using their web browser, click on one of our remote servers and they are RDC'ed in.

People though have a massive issue, with logging off. It seems to escape their head. All users are doing is clicking the Close button on the RDC Client, Which is not logging them off.

We are building a program to sort this out, The idea is to "hook" into the Remote Desktop API and then check if a session is disconnected, if it is, we log off the user.

The program would be running in the background as a service or a physical minimized EXE.

We are building this in C#. So does anyone know of any RDC Events that can be called using .NET 4? Ones that will allow us to know when the user is closing the session.

If you need anymore information on this, let me know.

Cheers

4

2 回答 2

6

知道了。

称呼

SystemEvents.SessionSwitch += new SessionSwitchEventHandle SystemEvents_SessionSwitch);

然后

        static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
    {
        if (e.Reason == SessionSwitchReason.RemoteDisconnect || e.Reason == SessionSwitchReason.ConsoleDisconnect)
        {
            // Log off the user...

        }
        else
        {
            // Physical Logon
        }
    }
于 2012-10-06T12:04:10.567 回答
1

这比上面的其他答案更好。

        public Form1()
    {
        InitializeComponent();

        if (!WTSRegisterSessionNotification(this.Handle, NOTIFY_FOR_THIS_SESSION))
        {
            Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
        }
    }

    [DllImport("user32.dll")]
    public static extern int ExitWindowsEx(int uFlags, int dwReason);

    [DllImport("WtsApi32.dll")]
    private static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)]int dwFlags);

    [DllImport("WtsApi32.dll")]
    private static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd);

    // constants that can be passed for the dwFlags parameter
    const int NOTIFY_FOR_THIS_SESSION = 0;
    const int NOTIFY_FOR_ALL_SESSIONS = 1;

    // message id to look for when processing the message (see sample code)
    const int WM_WTSSESSION_CHANGE = 0x2b1;

    // WParam values that can be received: 
    const int WTS_CONSOLE_CONNECT = 0x1; // A session was connected to the console terminal.
    const int WTS_CONSOLE_DISCONNECT = 0x2; // A session was disconnected from the console terminal.
    const int WTS_REMOTE_CONNECT = 0x3; // A session was connected to the remote terminal.
    const int WTS_REMOTE_DISCONNECT = 0x4; // A session was disconnected from the remote terminal.
    const int WTS_SESSION_LOGON = 0x5; // A user has logged on to the session.
    const int WTS_SESSION_LOGOFF = 0x6; // A user has logged off the session.
    const int WTS_SESSION_LOCK = 0x7; // A session has been locked.
    const int WTS_SESSION_UNLOCK = 0x8; // A session has been unlocked.
    const int WTS_SESSION_REMOTE_CONTROL = 0x9; // A session has changed its remote controlled status.

    protected override void OnHandleDestroyed(EventArgs e)
    {
        // unregister the handle before it gets destroyed
        WTSUnRegisterSessionNotification(this.Handle);
        base.OnHandleDestroyed(e);
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_WTSSESSION_CHANGE)
        {
            int value = m.WParam.ToInt32();
            if (value == WTS_REMOTE_DISCONNECT)
            {
                ExitWindowsEx(4, 0); // Logout the user on disconnect
            }
            else if (value == WTS_REMOTE_CONNECT)
            {
                MessageBox.Show("Welcome to the VPN. There is no need to Logout anymore, as when you close this session it will automatically log you out");
            }
        }
        base.WndProc(ref m);
    }
于 2012-10-06T13:28:53.807 回答