From ceb6f70b4d0c1bf3a30e160b90467e29ee01ea0d Mon Sep 17 00:00:00 2001 From: Riley McArdle Date: Mon, 6 May 2013 00:28:23 -0500 Subject: [PATCH] Improve the PuTTY Saved Sessions list to update automatically when any changes are made. --- CHANGELOG.TXT | 1 + mRemoteV1/Config/Config.Connections.Load.vb | 2 +- mRemoteV1/Config/PuttySessions.vb | 120 ++++++++++++++++---- mRemoteV1/Forms/frmMain.vb | 4 + 4 files changed, 104 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 9b690f769..1dfe2d4ba 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -16,6 +16,7 @@ Changed Internet Explorer to no longer force IE7 compatibility mode. Changed the "Launch PuTTY" button in the "Options" dialog to open PuTTY from the path the user has currently set, instead of what was previously saved. Improved update and announcement checking. + Improved the PuTTY Saved Sessions list to update automatically when any changes are made. Lowered required version of RDC from 6.1 to 6.0. 1.71 Beta 3 (2013-03-20): diff --git a/mRemoteV1/Config/Config.Connections.Load.vb b/mRemoteV1/Config/Config.Connections.Load.vb index 9a8d2d0d3..54d7e7219 100644 --- a/mRemoteV1/Config/Config.Connections.Load.vb +++ b/mRemoteV1/Config/Config.Connections.Load.vb @@ -166,7 +166,7 @@ Namespace Config If import = False Then SetMainFormText(ConnectionFileName) - PuttySessions.AddSessionsToTree(Tree.Node.TreeView) + PuttySessions.AddSessionsToTree() End If End Sub #End Region diff --git a/mRemoteV1/Config/PuttySessions.vb b/mRemoteV1/Config/PuttySessions.vb index b3d0221e8..33c9abfb2 100644 --- a/mRemoteV1/Config/PuttySessions.vb +++ b/mRemoteV1/Config/PuttySessions.vb @@ -1,16 +1,29 @@ Imports System.ComponentModel +Imports System.Management +Imports mRemoteNG.Messages Imports Microsoft.Win32 Imports mRemoteNG.Connection.Protocol -Imports mRemoteNG.Tree Imports mRemoteNG.My +Imports mRemoteNG.App.Runtime +Imports System.Security.Principal Namespace Config Public Class PuttySessions Private Const PuttySessionsKey As String = "Software\SimonTatham\PuTTY\Sessions" + Private Shared _rootTreeNode As TreeNode + Private Shared _eventWatcher As ManagementEventWatcher - Public Shared Sub AddSessionsToTree(ByVal treeView As TreeView) - Dim savedSessions() As Connection.Info = LoadSessions() - If savedSessions Is Nothing OrElse savedSessions.Length = 0 Then Return + Private Delegate Sub AddSessionsToTreeDelegate() + Public Shared Sub AddSessionsToTree() + Dim treeView As TreeView = Tree.Node.TreeView + If treeView Is Nothing Then Return + If treeView.InvokeRequired Then + treeView.Invoke(New AddSessionsToTreeDelegate(AddressOf AddSessionsToTree)) + Return + End If + + Dim savedSessions As New List(Of Connection.Info)(LoadSessions()) + If savedSessions Is Nothing OrElse savedSessions.Count = 0 Then Return Dim puttyRootInfo As New Root.PuttySessions.Info() If String.IsNullOrEmpty(My.Settings.PuttySavedSessionsName) Then @@ -24,35 +37,72 @@ Namespace Config puttyRootInfo.Panel = My.Settings.PuttySavedSessionsPanel End If - Dim puttyRootNode As TreeNode = New TreeNode - puttyRootNode.Text = puttyRootInfo.Name - puttyRootNode.Tag = puttyRootInfo - puttyRootNode.ImageIndex = Images.Enums.TreeImage.PuttySessions - puttyRootNode.SelectedImageIndex = Images.Enums.TreeImage.PuttySessions + Dim inUpdate As Boolean = False - puttyRootInfo.TreeNode = puttyRootNode + If _rootTreeNode Is Nothing Then + _rootTreeNode = New TreeNode + _rootTreeNode.Name = puttyRootInfo.Name + _rootTreeNode.Text = puttyRootInfo.Name + _rootTreeNode.Tag = puttyRootInfo + _rootTreeNode.ImageIndex = Images.Enums.TreeImage.PuttySessions + _rootTreeNode.SelectedImageIndex = Images.Enums.TreeImage.PuttySessions + treeView.Nodes.Add(_rootTreeNode) + If Not inUpdate Then + treeView.BeginUpdate() + inUpdate = True + End If + End If - treeView.BeginUpdate() - treeView.Nodes.Add(puttyRootNode) + puttyRootInfo.TreeNode = _rootTreeNode - Dim newTreeNode As TreeNode + Dim newTreeNodes As New List(Of TreeNode) For Each sessionInfo As Connection.PuttySession.Info In savedSessions - newTreeNode = Node.AddNode(Node.Type.PuttySession, sessionInfo.Name) - If newTreeNode Is Nothing Then Continue For + Dim treeNode As TreeNode + Dim isNewNode As Boolean + If _rootTreeNode.Nodes.ContainsKey(sessionInfo.Name) Then + treeNode = _rootTreeNode.Nodes.Item(sessionInfo.Name) + isNewNode = False + Else + treeNode = Tree.Node.AddNode(Tree.Node.Type.PuttySession, sessionInfo.Name) + If treeNode Is Nothing Then Continue For + treeNode.Name = treeNode.Text + treeNode.ImageIndex = Images.Enums.TreeImage.ConnectionClosed + treeNode.SelectedImageIndex = Images.Enums.TreeImage.ConnectionClosed + isNewNode = True + End If sessionInfo.RootPuttySessionsInfo = puttyRootInfo - sessionInfo.TreeNode = newTreeNode + sessionInfo.TreeNode = treeNode sessionInfo.Inherit.TurnOffInheritanceCompletely() - newTreeNode.Tag = sessionInfo - newTreeNode.ImageIndex = Images.Enums.TreeImage.ConnectionClosed - newTreeNode.SelectedImageIndex = Images.Enums.TreeImage.ConnectionClosed + treeNode.Tag = sessionInfo - puttyRootNode.Nodes.Add(newTreeNode) + If isNewNode Then newTreeNodes.Add(treeNode) Next - puttyRootNode.Expand() - treeView.EndUpdate() + For Each treeNode As TreeNode In _rootTreeNode.Nodes + If Not savedSessions.Contains(treeNode.Tag) Then + If Not inUpdate Then + treeView.BeginUpdate() + inUpdate = True + End If + _rootTreeNode.Nodes.Remove(treeNode) + End If + Next + + If Not newTreeNodes.Count = 0 Then + If Not inUpdate Then + treeView.BeginUpdate() + inUpdate = True + End If + _rootTreeNode.Nodes.AddRange(newTreeNodes.ToArray()) + End If + + If inUpdate Then + Tree.Node.Sort(_rootTreeNode, SortOrder.Ascending) + _rootTreeNode.Expand() + treeView.EndUpdate() + End If End Sub Protected Shared Function GetSessionNames(Optional ByVal raw As Boolean = False) As String() @@ -139,6 +189,32 @@ Namespace Config Return sessionInfo End Function + Public Shared Sub StartWatcher() + If _eventWatcher IsNot Nothing Then Return + + Try + Dim currentUserSid As String = WindowsIdentity.GetCurrent().User.Value + Dim key As String = String.Join("\", {currentUserSid, PuttySessionsKey}).Replace("\", "\\") + Dim query As New WqlEventQuery(String.Format("SELECT * FROM RegistryTreeChangeEvent WHERE Hive = 'HKEY_USERS' AND RootPath = '{0}'", key)) + _eventWatcher = New ManagementEventWatcher(query) + AddHandler _eventWatcher.EventArrived, AddressOf OnManagementEventArrived + _eventWatcher.Start() + Catch ex As Exception + MessageCollector.AddExceptionMessage("PuttySessions.Watcher.StartWatching() failed.", ex, MessageClass.WarningMsg, True) + End Try + End Sub + + Public Shared Sub StopWatcher() + If _eventWatcher Is Nothing Then Return + _eventWatcher.Stop() + _eventWatcher.Dispose() + _eventWatcher = Nothing + End Sub + + Private Shared Sub OnManagementEventArrived(ByVal sender As Object, ByVal e As EventArrivedEventArgs) + AddSessionsToTree() + End Sub + Public Class SessionList Inherits StringConverter diff --git a/mRemoteV1/Forms/frmMain.vb b/mRemoteV1/Forms/frmMain.vb index f095eb5a8..e0f95ae7c 100644 --- a/mRemoteV1/Forms/frmMain.vb +++ b/mRemoteV1/Forms/frmMain.vb @@ -76,6 +76,8 @@ Public Class frmMain Return End If + PuttySessions.StartWatcher() + If My.Settings.StartupComponentsCheck Then Windows.Show(UI.Window.Type.ComponentsCheck) End If @@ -247,6 +249,8 @@ Public Class frmMain End If End If + PuttySessions.StopWatcher() + Shutdown.BeforeQuit() _IsClosing = True