From 7f36b7926bb1be4f79eebce45a3099bb01d5f768 Mon Sep 17 00:00:00 2001 From: Riley McArdle Date: Sat, 23 Mar 2013 13:58:39 -0500 Subject: [PATCH] Fix issue MR-392 - Sessions Panel - context menu entries need to be context aware Refactor UI.Window.Sessions. --- CHANGELOG.TXT | 1 + mRemoteV1/Language/Language.Designer.vb | 11 +- mRemoteV1/Language/Language.resx | 5 +- mRemoteV1/UI/UI.Window.Sessions.Designer.vb | 100 ++++ mRemoteV1/UI/UI.Window.Sessions.resx | 5 +- mRemoteV1/UI/UI.Window.Sessions.vb | 579 +++++++------------- mRemoteV1/UI/UI.Window.Tree.vb | 3 +- mRemoteV1/mRemoteV1.vbproj | 3 + 8 files changed, 333 insertions(+), 374 deletions(-) create mode 100644 mRemoteV1/UI/UI.Window.Sessions.Designer.vb diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index a86aeae65..950d4478f 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,3 +1,4 @@ + Fixed issue MR-392 - Sessions Panel - context menu entries need to be context aware Fixed issue MR-422 - Gives error Object reference not set to an instance of an object. Fixed an exception or crash when choosing unnamed colors for themes. Fixed possible error "Control does not support transparent background colors" when modifying themes. diff --git a/mRemoteV1/Language/Language.Designer.vb b/mRemoteV1/Language/Language.Designer.vb index 7e03042bf..d87010b33 100644 --- a/mRemoteV1/Language/Language.Designer.vb +++ b/mRemoteV1/Language/Language.Designer.vb @@ -2968,6 +2968,15 @@ Namespace My End Get End Property + ''' + ''' Looks up a localized string similar to Retrieve. + ''' + Friend Shared ReadOnly Property strMenuSessionRetrieve() As String + Get + Return ResourceManager.GetString("strMenuSessionRetrieve", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Sessions. ''' @@ -4854,7 +4863,7 @@ Namespace My End Property ''' - ''' Looks up a localized string similar to Open RDP Connectin failed!. + ''' Looks up a localized string similar to Open RDP Connection failed!. ''' Friend Shared ReadOnly Property strRdpOpenConnectionFailed() As String Get diff --git a/mRemoteV1/Language/Language.resx b/mRemoteV1/Language/Language.resx index bef015fb2..1820e4dbc 100644 --- a/mRemoteV1/Language/Language.resx +++ b/mRemoteV1/Language/Language.resx @@ -1677,7 +1677,7 @@ Message: GetSessions failed! - Open RDP Connectin failed! + Open RDP Connection failed! RDP reconnection count: @@ -2223,4 +2223,7 @@ mRemoteNG will now quit and begin with the installation. {0} has detected the Lenovo Auto Scroll Utility running on this system. This utility is known to cause problems with {0}. It is recommended that you disable or uninstall it. + + Retrieve + \ No newline at end of file diff --git a/mRemoteV1/UI/UI.Window.Sessions.Designer.vb b/mRemoteV1/UI/UI.Window.Sessions.Designer.vb new file mode 100644 index 000000000..6568b7d02 --- /dev/null +++ b/mRemoteV1/UI/UI.Window.Sessions.Designer.vb @@ -0,0 +1,100 @@ +Namespace UI + Namespace Window + Partial Public Class Sessions + Inherits Base +#Region " Windows Form Designer generated code " + Private components As System.ComponentModel.IContainer + Friend WithEvents sessionMenuRetrieve As System.Windows.Forms.ToolStripMenuItem + Friend WithEvents sessionMenuLogoff As System.Windows.Forms.ToolStripMenuItem + Friend WithEvents sessionList As System.Windows.Forms.ListView + + Private Sub InitializeComponent() + Me.components = New System.ComponentModel.Container() + Dim sessionMenu As System.Windows.Forms.ContextMenuStrip + Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(Sessions)) + Me.sessionMenuRetrieve = New System.Windows.Forms.ToolStripMenuItem() + Me.sessionMenuLogoff = New System.Windows.Forms.ToolStripMenuItem() + Me.sessionList = New System.Windows.Forms.ListView() + Me.sessionUsernameColumn = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) + Me.sessionActivityColumn = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) + Me.sessionTypeColumn = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader) + sessionMenu = New System.Windows.Forms.ContextMenuStrip(Me.components) + sessionMenu.SuspendLayout() + Me.SuspendLayout() + ' + 'sessionMenu + ' + sessionMenu.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.sessionMenuRetrieve, Me.sessionMenuLogoff}) + sessionMenu.Name = "cMenSession" + sessionMenu.Size = New System.Drawing.Size(153, 70) + AddHandler sessionMenu.Opening, AddressOf Me.menuSession_Opening + ' + 'sessionMenuRetrieve + ' + Me.sessionMenuRetrieve.Image = Global.mRemoteNG.My.Resources.Resources.Refresh + Me.sessionMenuRetrieve.Name = "sessionMenuRetrieve" + Me.sessionMenuRetrieve.Size = New System.Drawing.Size(152, 22) + Me.sessionMenuRetrieve.Text = "Retrieve" + ' + 'sessionMenuLogoff + ' + Me.sessionMenuLogoff.Image = Global.mRemoteNG.My.Resources.Resources.Session_LogOff + Me.sessionMenuLogoff.Name = "sessionMenuLogoff" + Me.sessionMenuLogoff.Size = New System.Drawing.Size(152, 22) + Me.sessionMenuLogoff.Text = Global.mRemoteNG.My.Language.strLogOff + ' + 'sessionList + ' + Me.sessionList.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ + Or System.Windows.Forms.AnchorStyles.Left) _ + Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) + Me.sessionList.BorderStyle = System.Windows.Forms.BorderStyle.None + Me.sessionList.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.sessionUsernameColumn, Me.sessionActivityColumn, Me.sessionTypeColumn}) + Me.sessionList.ContextMenuStrip = sessionMenu + Me.sessionList.FullRowSelect = True + Me.sessionList.GridLines = True + Me.sessionList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable + Me.sessionList.Location = New System.Drawing.Point(0, -1) + Me.sessionList.MultiSelect = False + Me.sessionList.Name = "sessionList" + Me.sessionList.ShowGroups = False + Me.sessionList.Size = New System.Drawing.Size(242, 174) + Me.sessionList.TabIndex = 0 + Me.sessionList.UseCompatibleStateImageBehavior = False + Me.sessionList.View = System.Windows.Forms.View.Details + ' + 'sessionUsernameColumn + ' + Me.sessionUsernameColumn.Text = Global.mRemoteNG.My.Language.strColumnUsername + Me.sessionUsernameColumn.Width = 80 + ' + 'sessionActivityColumn + ' + Me.sessionActivityColumn.Text = Global.mRemoteNG.My.Language.strActivity + ' + 'sessionTypeColumn + ' + Me.sessionTypeColumn.Text = Global.mRemoteNG.My.Language.strType + Me.sessionTypeColumn.Width = 80 + ' + 'Sessions + ' + Me.ClientSize = New System.Drawing.Size(242, 173) + Me.Controls.Add(Me.sessionList) + Me.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) + Me.HideOnClose = True + Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) + Me.Name = "Sessions" + Me.TabText = Global.mRemoteNG.My.Language.strMenuSessions + Me.Text = "Sessions" + sessionMenu.ResumeLayout(False) + Me.ResumeLayout(False) + + End Sub + Friend WithEvents sessionUsernameColumn As System.Windows.Forms.ColumnHeader + Friend WithEvents sessionActivityColumn As System.Windows.Forms.ColumnHeader + Friend WithEvents sessionTypeColumn As System.Windows.Forms.ColumnHeader +#End Region + End Class + End Namespace +End Namespace diff --git a/mRemoteV1/UI/UI.Window.Sessions.resx b/mRemoteV1/UI/UI.Window.Sessions.resx index 06ac72a0f..e42d30c83 100644 --- a/mRemoteV1/UI/UI.Window.Sessions.resx +++ b/mRemoteV1/UI/UI.Window.Sessions.resx @@ -117,7 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + False + + 14, 16 diff --git a/mRemoteV1/UI/UI.Window.Sessions.vb b/mRemoteV1/UI/UI.Window.Sessions.vb index 3523ca5bd..b5d4d0f46 100644 --- a/mRemoteV1/UI/UI.Window.Sessions.vb +++ b/mRemoteV1/UI/UI.Window.Sessions.vb @@ -1,412 +1,253 @@ -Imports WeifenLuo.WinFormsUI.Docking +Imports System.Threading +Imports mRemoteNG.My +Imports WeifenLuo.WinFormsUI.Docking Imports mRemoteNG.App.Runtime Namespace UI Namespace Window Public Class Sessions - Inherits UI.Window.Base - -#Region "Form Init" - Friend WithEvents clmSesType As System.Windows.Forms.ColumnHeader - Friend WithEvents clmSesUsername As System.Windows.Forms.ColumnHeader - Friend WithEvents clmSesActivity As System.Windows.Forms.ColumnHeader - Friend WithEvents cMenSession As System.Windows.Forms.ContextMenuStrip - Private components As System.ComponentModel.IContainer - Friend WithEvents cMenSessionRefresh As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents cMenSessionLogOff As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents lvSessions As System.Windows.Forms.ListView - - Private Sub InitializeComponent() - Me.components = New System.ComponentModel.Container - Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(Sessions)) - Me.lvSessions = New System.Windows.Forms.ListView - Me.clmSesUsername = New System.Windows.Forms.ColumnHeader - Me.clmSesActivity = New System.Windows.Forms.ColumnHeader - Me.clmSesType = New System.Windows.Forms.ColumnHeader - Me.cMenSession = New System.Windows.Forms.ContextMenuStrip(Me.components) - Me.cMenSessionRefresh = New System.Windows.Forms.ToolStripMenuItem - Me.cMenSessionLogOff = New System.Windows.Forms.ToolStripMenuItem - Me.cMenSession.SuspendLayout() - Me.SuspendLayout() - ' - 'lvSessions - ' - Me.lvSessions.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ - Or System.Windows.Forms.AnchorStyles.Left) _ - Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) - Me.lvSessions.BorderStyle = System.Windows.Forms.BorderStyle.None - Me.lvSessions.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.clmSesUsername, Me.clmSesActivity, Me.clmSesType}) - Me.lvSessions.ContextMenuStrip = Me.cMenSession - Me.lvSessions.FullRowSelect = True - Me.lvSessions.GridLines = True - Me.lvSessions.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable - Me.lvSessions.Location = New System.Drawing.Point(0, -1) - Me.lvSessions.MultiSelect = False - Me.lvSessions.Name = "lvSessions" - Me.lvSessions.ShowGroups = False - Me.lvSessions.Size = New System.Drawing.Size(242, 174) - Me.lvSessions.TabIndex = 0 - Me.lvSessions.UseCompatibleStateImageBehavior = False - Me.lvSessions.View = System.Windows.Forms.View.Details - ' - 'clmSesUsername - ' - Me.clmSesUsername.Text = My.Language.strColumnUsername - Me.clmSesUsername.Width = 80 - ' - 'clmSesActivity - ' - Me.clmSesActivity.Text = My.Language.strActivity - ' - 'clmSesType - ' - Me.clmSesType.Text = My.Language.strType - Me.clmSesType.Width = 80 - ' - 'cMenSession - ' - Me.cMenSession.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.cMenSessionRefresh, Me.cMenSessionLogOff}) - Me.cMenSession.Name = "cMenSession" - Me.cMenSession.Size = New System.Drawing.Size(124, 48) - ' - 'cMenSessionRefresh - ' - Me.cMenSessionRefresh.Image = Global.mRemoteNG.My.Resources.Resources.Refresh - Me.cMenSessionRefresh.Name = "cMenSessionRefresh" - Me.cMenSessionRefresh.Size = New System.Drawing.Size(123, 22) - Me.cMenSessionRefresh.Text = My.Language.strRefresh - ' - 'cMenSessionLogOff - ' - Me.cMenSessionLogOff.Image = Global.mRemoteNG.My.Resources.Resources.Session_LogOff - Me.cMenSessionLogOff.Name = "cMenSessionLogOff" - Me.cMenSessionLogOff.Size = New System.Drawing.Size(123, 22) - Me.cMenSessionLogOff.Text = My.Language.strLogOff - ' - 'Sessions - ' - Me.ClientSize = New System.Drawing.Size(242, 173) - Me.Controls.Add(Me.lvSessions) - Me.HideOnClose = True - Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) - Me.Name = "Sessions" - Me.TabText = My.Language.strMenuSessions - Me.Text = My.Language.strMenuSessions - Me.cMenSession.ResumeLayout(False) - Me.ResumeLayout(False) - - End Sub -#End Region - -#Region "Private Properties" - Private tServerName As String - Private tUserName As String - Private tPassword As String - Private tDomain As String - Private tSessionID As Long - Private tKillingSession As Boolean - Private threadSessions As Threading.Thread - Private tServerHandle As Long -#End Region - -#Region "Public Properties" - Private _CurrentHost As String - Public Property CurrentHost() As String - Get - Return Me._CurrentHost - End Get - Set(ByVal value As String) - Me._CurrentHost = value - End Set - End Property -#End Region - -#Region "Form Stuff" - Private Sub Sessions_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - ApplyLanguage() - End Sub - - Private Sub ApplyLanguage() - clmSesUsername.Text = My.Language.strColumnUsername - clmSesActivity.Text = My.Language.strActivity - clmSesType.Text = My.Language.strType - cMenSessionRefresh.Text = My.Language.strRefresh - cMenSessionLogOff.Text = My.Language.strLogOff - TabText = My.Language.strMenuSessions - Text = My.Language.strMenuSessions - End Sub -#End Region - -#Region "Private Methods" - Private Sub GetSessionsBG() - Try - Dim tS As New mRemoteNG.Connection.Protocol.RDP.TerminalSessions - Dim sU As New Security.Impersonator - Dim tsSessions As New mRemoteNG.Connection.Protocol.RDP.Sessions - - sU.StartImpersonation(tDomain, tUserName, tPassword) - - Try - 'Trace.WriteLine("Opening connection to server: " & tServerName) - If tS.OpenConnection(tServerName) = True Then - tServerHandle = tS.ServerHandle - 'Trace.WriteLine("Trying to get sessions") - tsSessions = tS.GetSessions - End If - Catch ex As Exception - End Try - - Dim i As Integer = 0 - - 'Trace.WriteLine("Sessions Count: " & tsSessions.Count) - - If tServerName = Me._CurrentHost Then - For i = 0 To tsSessions.ItemsCount - 1 - Dim lItem As New ListViewItem - lItem.Tag = tsSessions(i).SessionID - lItem.Text = tsSessions(i).SessionUser - lItem.SubItems.Add(tsSessions(i).SessionState) - lItem.SubItems.Add(Replace(tsSessions(i).SessionName, vbNewLine, "")) - - 'Trace.WriteLine("Session " & i & ": " & tsSessions(i).SessionUser) - - AddToList(lItem) - Next - End If - - sU.StopImpersonation() - sU = Nothing - tS.CloseConnection(tServerHandle) - Catch ex As Exception - MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strSessionGetFailed & vbNewLine & ex.Message, True) - End Try - End Sub - - Private Sub KillSessionBG() - Try - If tUserName = "" Or tPassword = "" Then - 'Trace.WriteLine("No Logon Info") - Exit Sub - End If - - Dim ts As New mRemoteNG.Connection.Protocol.RDP.TerminalSessions - Dim sU As New Security.Impersonator - - sU.StartImpersonation(tDomain, tUserName, tPassword) - - Try - If ts.OpenConnection(tServerName) = True Then - If ts.KillSession(tSessionID) = True Then - sU.StopImpersonation() - 'Trace.WriteLine("Successfully killed session: " & tSessionID) - Else - sU.StopImpersonation() - 'Trace.WriteLine("Killing session " & tSessionID & " failed") - End If - End If - Catch ex As Exception - sU.StopImpersonation() - End Try - - sU.StopImpersonation() - - ClearList() - - GetSessionsBG() - Catch ex As Exception - MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strSessionKillFailed & vbNewLine & ex.Message, True) - End Try - End Sub - - - Delegate Sub AddToListCB(ByVal [ListItem] As ListViewItem) - Private Sub AddToList(ByVal [ListItem] As ListViewItem) - If Me.lvSessions.InvokeRequired Then - Dim d As New AddToListCB(AddressOf AddToList) - Me.lvSessions.Invoke(d, New Object() {[ListItem]}) - Else - Me.lvSessions.Items.Add(ListItem) - End If - End Sub - - Delegate Sub ClearListCB() - Private Sub ClearList() - If Me.lvSessions.InvokeRequired Then - Dim d As New ClearListCB(AddressOf ClearList) - Me.lvSessions.Invoke(d) - Else - Me.lvSessions.Items.Clear() - End If - End Sub - - Private Sub cMenSessionRefresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cMenSessionRefresh.Click - Me.GetSessions() - End Sub - - Private Sub cMenSessionLogOff_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cMenSessionLogOff.Click - Me.KillSession() - End Sub + Inherits Base +#Region "Private Fields" + Private _getSessionsThread As Thread + Private _retrieved As Boolean = False #End Region #Region "Public Methods" - Public Sub New(ByVal Panel As DockContent) - Me.WindowType = Type.Sessions - Me.DockPnl = Panel - Me.InitializeComponent() + Public Sub New(ByVal panel As DockContent) + WindowType = Type.Sessions + DockPnl = panel + InitializeComponent() End Sub - Public Sub GetSessionsAuto() + Public Sub GetSessions(Optional ByVal auto As Boolean = False) + ClearList() + If auto Then + _retrieved = False + If Not Settings.AutomaticallyGetSessionInfo Then Return + End If + Try - Dim nowHost As String = "" + Dim connectionInfo As mRemoteNG.Connection.Info = TryCast(mRemoteNG.Tree.Node.SelectedNode.Tag, mRemoteNG.Connection.Info) + If connectionInfo Is Nothing Then Return - If TypeOf mRemoteNG.Tree.Node.SelectedNode.Tag Is mRemoteNG.Connection.Info Then - nowHost = TryCast(mRemoteNG.Tree.Node.SelectedNode.Tag, mRemoteNG.Connection.Info).Hostname - Else - Me.ClearList() - Exit Sub - End If + If Not (connectionInfo.Protocol = mRemoteNG.Connection.Protocol.Protocols.RDP Or _ + connectionInfo.Protocol = mRemoteNG.Connection.Protocol.Protocols.ICA) Then Return - If My.Settings.AutomaticallyGetSessionInfo And Me._CurrentHost = nowHost Then - Dim conI As mRemoteNG.Connection.Info = mRemoteNG.Tree.Node.SelectedNode.Tag + Dim data As New BackgroundData + With data + .Hostname = connectionInfo.Hostname + .Username = connectionInfo.Username + .Password = connectionInfo.Password + .Domain = connectionInfo.Domain - If conI.Protocol = mRemoteNG.Connection.Protocol.Protocols.RDP Or conI.Protocol = mRemoteNG.Connection.Protocol.Protocols.ICA Then - 'continue - Else - Me.ClearList() - Exit Sub - End If - - Dim sUser As String = conI.Username - Dim sPass As String = conI.Password - Dim sDom As String = conI.Domain - - If My.Settings.EmptyCredentials = "custom" Then - If sUser = "" Then - sUser = My.Settings.DefaultUsername + If Settings.EmptyCredentials = "custom" Then + If .Username = "" Then + .Username = Settings.DefaultUsername End If - If sPass = "" Then - sPass = Security.Crypt.Decrypt(My.Settings.DefaultPassword, App.Info.General.EncryptionKey) + If .Password = "" Then + .Password = Security.Crypt.Decrypt(Settings.DefaultPassword, App.Info.General.EncryptionKey) End If - If sDom = "" Then - sDom = My.Settings.DefaultDomain + If .Domain = "" Then + .Domain = Settings.DefaultDomain End If End If + End With - Me.GetSessions(conI.Hostname, sUser, sPass, sDom) + If _getSessionsThread IsNot Nothing Then + If _getSessionsThread.IsAlive Then _getSessionsThread.Abort() End If + _getSessionsThread = New Thread(AddressOf GetSessionsBackground) + _getSessionsThread.SetApartmentState(ApartmentState.STA) + _getSessionsThread.IsBackground = True + _getSessionsThread.Start(data) Catch ex As Exception - MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "GetSessionsAuto (UI.Window.Sessions) failed" & vbNewLine & ex.Message, True) - End Try - End Sub - - Public Sub GetSessions() - If mRemoteNG.Tree.Node.SelectedNode Is Nothing Then - Exit Sub - End If - - If TypeOf mRemoteNG.Tree.Node.SelectedNode.Tag Is mRemoteNG.Connection.Info Then - 'continue - Else - Me.ClearList() - Exit Sub - End If - - Dim conI As mRemoteNG.Connection.Info = mRemoteNG.Tree.Node.SelectedNode.Tag - - If conI.Protocol = mRemoteNG.Connection.Protocol.Protocols.RDP Or conI.Protocol = mRemoteNG.Connection.Protocol.Protocols.ICA Then - 'continue - Else - Me.ClearList() - Exit Sub - End If - - Me._CurrentHost = conI.Hostname - - Dim sUser As String = conI.Username - Dim sPass As String = conI.Password - Dim sDom As String = conI.Domain - - If My.Settings.EmptyCredentials = "custom" Then - If sUser = "" Then - sUser = My.Settings.DefaultUsername - End If - - If sPass = "" Then - sPass = Security.Crypt.Decrypt(My.Settings.DefaultPassword, App.Info.General.EncryptionKey) - End If - - If sDom = "" Then - sDom = My.Settings.DefaultDomain - End If - End If - - Me.GetSessions(conI.Hostname, sUser, sPass, sDom) - End Sub - - Public Sub GetSessions(ByVal ServerName As String, ByVal Username As String, ByVal Password As String, ByVal Domain As String) - Try - Me.lvSessions.Items.Clear() - - tServerName = ServerName - tUserName = Username - tPassword = Password - tDomain = Domain - - threadSessions = New Threading.Thread(AddressOf GetSessionsBG) - threadSessions.SetApartmentState(Threading.ApartmentState.STA) - threadSessions.IsBackground = True - threadSessions.Start() - Catch ex As Exception - MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "GetSessions (UI.Window.Sessions) failed" & vbNewLine & ex.Message, True) + MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "UI.Window.Sessions.GetSessions() failed." & vbNewLine & ex.Message, True) End Try End Sub Public Sub KillSession() - If TypeOf mRemoteNG.Tree.Node.SelectedNode.Tag Is mRemoteNG.Connection.Info Then - 'continue - Else - Exit Sub - End If + If sessionList.SelectedItems.Count = 0 Then Return - Dim conI As mRemoteNG.Connection.Info = mRemoteNG.Tree.Node.SelectedNode.Tag + Dim connectionInfo As mRemoteNG.Connection.Info = TryCast(mRemoteNG.Tree.Node.SelectedNode.Tag, mRemoteNG.Connection.Info) + If connectionInfo Is Nothing Then Return - If conI.Protocol = mRemoteNG.Connection.Protocol.Protocols.RDP Then - 'continue - Else - Exit Sub - End If + If Not connectionInfo.Protocol = mRemoteNG.Connection.Protocol.Protocols.RDP Then Return - If Me.lvSessions.SelectedItems.Count > 0 Then - 'continue - Else - Exit Sub - End If - - For Each lvItem As ListViewItem In Me.lvSessions.SelectedItems - Me.KillSession(conI.Hostname, conI.Username, conI.Password, conI.Domain, lvItem.Tag) + For Each lvItem As ListViewItem In sessionList.SelectedItems + KillSession(connectionInfo.Hostname, connectionInfo.Username, connectionInfo.Password, connectionInfo.Domain, lvItem.Tag) Next End Sub - Public Sub KillSession(ByVal ServerName As String, ByVal Username As String, ByVal Password As String, ByVal Domain As String, ByVal SessionID As String) + Public Sub KillSession(ByVal hostname As String, ByVal username As String, ByVal password As String, ByVal domain As String, ByVal sessionId As String) Try - tServerName = ServerName - tUserName = Username - tPassword = Password - tDomain = Domain - tSessionID = SessionID + Dim data As New BackgroundData + With data + .Hostname = hostname + .Username = username + .Password = password + .Domain = domain + .SessionId = sessionId + End With - threadSessions = New Threading.Thread(AddressOf KillSessionBG) - threadSessions.SetApartmentState(Threading.ApartmentState.STA) - threadSessions.IsBackground = True - threadSessions.Start() + Dim thread As New Thread(AddressOf KillSessionBackground) + thread.SetApartmentState(ApartmentState.STA) + thread.IsBackground = True + thread.Start(data) Catch ex As Exception - MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "KillSession (UI.Window.Sessions) failed" & vbNewLine & ex.Message, True) + MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "UI.Window.Sessions.KillSession() failed." & vbNewLine & ex.Message, True) End Try End Sub #End Region +#Region "Private Methods" +#Region "Form Stuff" + Private Sub Sessions_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load + ApplyLanguage() + End Sub + + Private Sub ApplyLanguage() + TabText = Language.strMenuSessions + Text = Language.strMenuSessions + sessionActivityColumn.Text = Language.strActivity + sessionMenuLogoff.Text = Language.strLogOff + sessionMenuRetrieve.Text = Language.strMenuSessionRetrieve + sessionTypeColumn.Text = Language.strType + sessionUsernameColumn.Text = Language.strColumnUsername + End Sub +#End Region + + Private Sub GetSessionsBackground(ByVal dataObject As Object) + Dim data As BackgroundData = TryCast(dataObject, BackgroundData) + If data Is Nothing Then Return + + Dim impersonator As New Security.Impersonator + Dim terminalSessions As New mRemoteNG.Connection.Protocol.RDP.TerminalSessions + Dim serverHandle As Long = 0 + Try + With data + impersonator.StartImpersonation(.Domain, .Username, .Password) + + If Not terminalSessions.OpenConnection(.Hostname) Then Return + serverHandle = terminalSessions.ServerHandle + + GetSessions(terminalSessions) + End With + + _retrieved = True + Catch ex As ThreadAbortException + + Catch ex As Exception + MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, Language.strSessionGetFailed & vbNewLine & ex.Message, True) + Finally + impersonator.StopImpersonation() + If Not serverHandle = 0 Then + terminalSessions.CloseConnection(serverHandle) + End If + End Try + End Sub + + ' Get sessions from an already impersonated and connected TerminalSessions object + Private Sub GetSessions(ByVal terminalSessions As mRemoteNG.Connection.Protocol.RDP.TerminalSessions) + Dim rdpSessions As mRemoteNG.Connection.Protocol.RDP.Sessions = terminalSessions.GetSessions + For Each session As mRemoteNG.Connection.Protocol.RDP.Session In rdpSessions + Dim item As New ListViewItem + item.Tag = session.SessionID + item.Text = session.SessionUser + item.SubItems.Add(session.SessionState) + item.SubItems.Add(Replace(session.SessionName, vbNewLine, "")) + AddToList(item) + Next + End Sub + + Private Sub KillSessionBackground(ByVal dataObject As Object) + Dim data As BackgroundData = TryCast(dataObject, BackgroundData) + If data Is Nothing Then Return + + Dim impersonator As New Security.Impersonator + Dim terminalSessions As New mRemoteNG.Connection.Protocol.RDP.TerminalSessions + Dim serverHandle As Long = 0 + Try + With data + If String.IsNullOrEmpty(.Username) Or String.IsNullOrEmpty(.Password) Then Return + + impersonator.StartImpersonation(.Domain, .Username, .Password) + + If terminalSessions.OpenConnection(.Hostname) Then + serverHandle = terminalSessions.ServerHandle + terminalSessions.KillSession(.SessionId) + End If + + ClearList() + GetSessions(terminalSessions) + + _retrieved = True + End With + Catch ex As ThreadAbortException + + Catch ex As Exception + MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, Language.strSessionKillFailed & vbNewLine & ex.Message, True) + Finally + impersonator.StopImpersonation() + If Not serverHandle = 0 Then + terminalSessions.CloseConnection(serverHandle) + End If + End Try + End Sub + + Delegate Sub AddToListCallback(ByVal item As ListViewItem) + Private Sub AddToList(ByVal item As ListViewItem) + If sessionList.InvokeRequired Then + Dim callback As New AddToListCallback(AddressOf AddToList) + sessionList.Invoke(callback, New Object() {item}) + Else + sessionList.Items.Add(item) + End If + End Sub + + Delegate Sub ClearListCallback() + Private Sub ClearList() + If sessionList.InvokeRequired Then + Dim callback As New ClearListCallback(AddressOf ClearList) + sessionList.Invoke(callback) + Else + sessionList.Items.Clear() + End If + End Sub + + Private Sub menuSession_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) + If _retrieved Then + sessionMenuRetrieve.Text = Language.strRefresh + Else + sessionMenuRetrieve.Text = Language.strMenuSessionRetrieve + End If + + If sessionList.SelectedItems.Count = 0 Then + sessionMenuLogoff.Enabled = False + Else + sessionMenuLogoff.Enabled = True + End If + End Sub + + Private Sub sessionMenuRetrieve_Click(ByVal sender As System.Object, ByVal e As EventArgs) Handles sessionMenuRetrieve.Click + GetSessions() + End Sub + + Private Sub sessionMenuLogoff_Click(ByVal sender As System.Object, ByVal e As EventArgs) Handles sessionMenuLogoff.Click + KillSession() + End Sub +#End Region + +#Region "Private Classes" + Private Class BackgroundData + Public Hostname As String + Public Username As String + Public Password As String + Public Domain As String + Public SessionId As Long + End Class +#End Region End Class End Namespace End Namespace \ No newline at end of file diff --git a/mRemoteV1/UI/UI.Window.Tree.vb b/mRemoteV1/UI/UI.Window.Tree.vb index f6bdc544d..3b814d492 100644 --- a/mRemoteV1/UI/UI.Window.Tree.vb +++ b/mRemoteV1/UI/UI.Window.Tree.vb @@ -589,7 +589,6 @@ Namespace UI Select Case mRemoteNG.Tree.Node.GetNodeType(e.Node) Case mRemoteNG.Tree.Node.Type.Connection, mRemoteNG.Tree.Node.Type.PuttySession Windows.configForm.SetPropertyGridObject(e.Node.Tag) - Windows.sessionsForm.CurrentHost = TryCast(e.Node.Tag, mRemoteNG.Connection.Info).Hostname Case mRemoteNG.Tree.Node.Type.Container Windows.configForm.SetPropertyGridObject(TryCast(e.Node.Tag, Container.Info).ConnectionInfo) Case mRemoteNG.Tree.Node.Type.Root, mRemoteNG.Tree.Node.Type.PuttyRoot @@ -600,7 +599,7 @@ Namespace UI Windows.configForm.pGrid_SelectedObjectChanged() ShowHideTreeContextMenuItems(e.Node) - Windows.sessionsForm.GetSessionsAuto() + Windows.sessionsForm.GetSessions(True) LastSelected = mRemoteNG.Tree.Node.GetConstantID(e.Node) Catch ex As Exception diff --git a/mRemoteV1/mRemoteV1.vbproj b/mRemoteV1/mRemoteV1.vbproj index 87456409b..5be391b02 100644 --- a/mRemoteV1/mRemoteV1.vbproj +++ b/mRemoteV1/mRemoteV1.vbproj @@ -331,6 +331,9 @@ Form + + UI.Window.Sessions.vb + Form