Merge branch 'develop' into feature/hotkeys

Conflicts:
	CHANGELOG.TXT
This commit is contained in:
Riley McArdle
2013-10-28 01:25:38 -05:00
27 changed files with 1181 additions and 723 deletions

View File

@@ -1,10 +1,27 @@
1.72:
Fixed issue MR-141 - Add a default protocol option
Fixed issue MR-367 - Make the 'Connect' button on the 'Quick Connect' toolbar a forced dropdown
Fixed misleading log messages about RD Gateway support.
Added feature MR-141 - Add a default protocol option
Added feature MR-547 - Add support for Xming Portable PuTTY
Made improvement MR-367 - Make the 'Connect' button on the 'Quick Connect' toolbar a forced dropdown
Added "Reset" to config panel context menu to allow resetting some config settings to their default value.
Removed misleading log messages about RD Gateway support.
Removed invalid "Site" configuration option from PuTTY Saved Sessions.
Fixed PuTTY Saved Sessions still showing if all saved sessions are removed.
Fixed config panel showing settings from previously loaded connection file after loading a new one.
1.71 (XXXX-XX-XX):
Fixed issue MR-574 - Crash when retrieving RDP session list if eolwtscom.dll is not registered
Fixed issue MR-578 - Connections file is reset
Fixed log file not showing operating system version on Windows XP and Windows Server 2003.
Fixed the wrong connections file opening on startup under certain conditions.
Fixed checking for updates even when disabled.
Improved error reporting when loading connections files.
Removed warning message when mRemoteNG is started for the first time about new connections file being created.
1.71 Release Candidate 2 (2013-10-16):
Fixed issue MR-560 - Cannot Auto-Update With Open Connections: Unable to find an entry point named 'TaskDialogIndirect' in DLL 'ComCtl32'
Fixed issue MR-565 - Double Folder keep heritage on the initial Folder
Fixed issue MR-566 - Typo in German UI Automatic Update Settings
Fixed duplicated folders possibly being named "New Connection" instead of the original folder's name.
1.71 Release Candidate 1 (2013-10-01):
Fixed issue MR-495 - Having a negative range in port scan creates memory exhaustion.

View File

@@ -5,6 +5,7 @@ Imports mRemoteNG.Messages
Imports mRemoteNG.Connection
Imports mRemoteNG.Tools
Imports PSTaskDialog
Imports mRemoteNG.Config.Putty
Imports WeifenLuo.WinFormsUI.Docking
Imports System.IO
Imports Crownwood
@@ -370,13 +371,13 @@ Namespace App
Dim isFipsPolicyEnabled As Boolean = False
' Windows XP/Windows Server 2003
regKey = Registry.LocalMachine.OpenSubKey("System\CurrentControlSet\Control\Lsa")
regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System\CurrentControlSet\Control\Lsa")
If regKey IsNot Nothing Then
If Not regKey.GetValue("FIPSAlgorithmPolicy") = 0 Then isFipsPolicyEnabled = True
End If
' Windows Vista/Windows Server 2008 and newer
regKey = Registry.LocalMachine.OpenSubKey("System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy")
regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy")
If regKey IsNot Nothing Then
If Not regKey.GetValue("Enabled") = 0 Then isFipsPolicyEnabled = True
End If
@@ -492,20 +493,30 @@ Namespace App
#End If
Log.InfoFormat("Command Line: {0}", Environment.GetCommandLineArgs)
Dim osVersion As String = String.Empty
Dim servicePack As String = String.Empty
Try
Dim servicePack As Integer
For Each managementObject As ManagementObject In New ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get()
servicePack = managementObject.GetPropertyValue("ServicePackMajorVersion")
If servicePack = 0 Then
Log.InfoFormat("{0} {1}", managementObject.GetPropertyValue("Caption").Trim, managementObject.GetPropertyValue("OSArchitecture"))
Else
Log.InfoFormat("{0} Service Pack {1} {2}", managementObject.GetPropertyValue("Caption").Trim, servicePack.ToString, managementObject.GetPropertyValue("OSArchitecture"))
End If
For Each managementObject As ManagementObject In New ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem WHERE Primary=True").Get()
osVersion = managementObject.GetPropertyValue("Caption").Trim()
Dim servicePackNumber As Integer = managementObject.GetPropertyValue("ServicePackMajorVersion")
If Not servicePackNumber = 0 Then servicePack = String.Format("Service Pack {0}", servicePackNumber)
Next
Catch ex As Exception
Log.WarnFormat("Error retrieving operating system information from WMI. {0}", ex.Message)
End Try
Dim architecture As String = String.Empty
Try
For Each managementObject As ManagementObject In New ManagementObjectSearcher("SELECT * FROM Win32_Processor WHERE DeviceID='CPU0'").Get()
Dim addressWidth As Integer = managementObject.GetPropertyValue("AddressWidth")
architecture = String.Format("{0}-bit", addressWidth)
Next
Catch ex As Exception
Log.WarnFormat("Error retrieving operating system address width from WMI. {0}", ex.Message)
End Try
Log.InfoFormat(String.Join(" ", Array.FindAll(New String() {osVersion, servicePack, architecture}, Function(s) Not String.IsNullOrEmpty(s))))
Log.InfoFormat("Microsoft .NET CLR {0}", Version.ToString)
Log.InfoFormat("System Culture: {0}/{1}", Thread.CurrentThread.CurrentUICulture.Name, Thread.CurrentThread.CurrentUICulture.NativeName)
End If
@@ -693,7 +704,7 @@ Namespace App
Public Shared Sub Cleanup()
Try
PuttySessions.StopWatcher()
Putty.Sessions.StopWatcher()
If NotificationAreaIcon IsNot Nothing Then
If NotificationAreaIcon.Disposed = False Then
@@ -968,41 +979,54 @@ Namespace App
ConnectionList = New Connection.List
ContainerList = New Container.List
Dim conL As New Config.Connections.Load
Dim connectionsLoad As New Connections.Load
My.Settings.LoadConsFromCustomLocation = False
If filename = GetDefaultStartupConnectionFileName() Then
My.Settings.LoadConsFromCustomLocation = False
Else
My.Settings.LoadConsFromCustomLocation = True
My.Settings.CustomConsPath = filename
End If
Directory.CreateDirectory(Path.GetDirectoryName(filename))
Dim xW As New XmlTextWriter(filename, System.Text.Encoding.UTF8)
xW.Formatting = Formatting.Indented
xW.Indentation = 4
xW.WriteStartDocument()
xW.WriteStartElement("Connections") ' Do not localize
xW.WriteAttributeString("Name", My.Language.strConnections)
xW.WriteAttributeString("Export", "", "False")
xW.WriteAttributeString("Protected", "", "GiUis20DIbnYzWPcdaQKfjE2H5jh//L5v4RGrJMGNXuIq2CttB/d/BxaBP2LwRhY")
xW.WriteAttributeString("ConfVersion", "", "2.5")
' Use File.Open with FileMode.CreateNew so that we don't overwrite an existing file
Using fileStream As FileStream = File.Open(filename, FileMode.CreateNew, FileAccess.Write, FileShare.None)
Using xmlTextWriter As New XmlTextWriter(fileStream, System.Text.Encoding.UTF8)
With xmlTextWriter
.Formatting = Formatting.Indented
.Indentation = 4
xW.WriteEndElement()
xW.WriteEndDocument()
.WriteStartDocument()
xW.Close()
.WriteStartElement("Connections") ' Do not localize
.WriteAttributeString("Name", My.Language.strConnections)
.WriteAttributeString("Export", "", "False")
.WriteAttributeString("Protected", "", "GiUis20DIbnYzWPcdaQKfjE2H5jh//L5v4RGrJMGNXuIq2CttB/d/BxaBP2LwRhY")
.WriteAttributeString("ConfVersion", "", "2.5")
conL.ConnectionList = ConnectionList
conL.ContainerList = ContainerList
.WriteEndElement()
.WriteEndDocument()
.Close()
End With
End Using
End Using
connectionsLoad.ConnectionList = ConnectionList
connectionsLoad.ContainerList = ContainerList
Tree.Node.ResetTree()
conL.RootTreeNode = Windows.treeForm.tvConnections.Nodes(0)
connectionsLoad.RootTreeNode = Windows.treeForm.tvConnections.Nodes(0)
' Load config
conL.ConnectionFileName = filename
conL.Load(False)
connectionsLoad.ConnectionFileName = filename
connectionsLoad.Load(False)
Windows.treeForm.tvConnections.SelectedNode = conL.RootTreeNode
Windows.treeForm.tvConnections.SelectedNode = connectionsLoad.RootTreeNode
Catch ex As Exception
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strCouldNotCreateNewConnectionsFile & vbNewLine & ex.Message)
MessageCollector.AddExceptionMessage(My.Language.strCouldNotCreateNewConnectionsFile, ex, MessageClass.ErrorMsg)
End Try
End Sub
@@ -1021,8 +1045,8 @@ Namespace App
LoadConnections(_withDialog, _loadUpdate)
End Sub
Public Shared Sub LoadConnections(Optional ByVal WithDialog As Boolean = False, Optional ByVal Update As Boolean = False)
Dim conL As New Config.Connections.Load
Public Shared Sub LoadConnections(Optional ByVal withDialog As Boolean = False, Optional ByVal update As Boolean = False)
Dim connectionsLoad As New Connections.Load
Try
Dim tmrWasEnabled As Boolean
@@ -1042,66 +1066,55 @@ Namespace App
ConnectionList = New Connection.List
ContainerList = New Container.List
If My.Settings.UseSQLServer = False Then
If WithDialog Then
Dim lD As OpenFileDialog = Tools.Controls.ConnectionsLoadDialog
If Not My.Settings.UseSQLServer Then
If withDialog Then
Dim loadDialog As OpenFileDialog = Tools.Controls.ConnectionsLoadDialog
If lD.ShowDialog = System.Windows.Forms.DialogResult.OK Then
conL.ConnectionFileName = lD.FileName
If loadDialog.ShowDialog = System.Windows.Forms.DialogResult.OK Then
connectionsLoad.ConnectionFileName = loadDialog.FileName
Else
Exit Sub
End If
Else
conL.ConnectionFileName = GetStartupConnectionFileName()
connectionsLoad.ConnectionFileName = GetStartupConnectionFileName()
End If
If File.Exists(conL.ConnectionFileName) = False Then
If WithDialog Then
MessageCollector.AddMessage(Messages.MessageClass.WarningMsg, String.Format(My.Language.strConnectionsFileCouldNotBeLoaded, conL.ConnectionFileName))
Else
MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, String.Format(My.Language.strConnectionsFileCouldNotBeLoadedNew, conL.ConnectionFileName))
App.Runtime.NewConnections(conL.ConnectionFileName)
End If
Exit Sub
End If
CreateBackupFile(conL.ConnectionFileName)
CreateBackupFile(connectionsLoad.ConnectionFileName)
End If
conL.ConnectionList = ConnectionList
conL.ContainerList = ContainerList
connectionsLoad.ConnectionList = ConnectionList
connectionsLoad.ContainerList = ContainerList
If PreviousConnectionList IsNot Nothing And PreviousContainerList IsNot Nothing Then
conL.PreviousConnectionList = PreviousConnectionList
conL.PreviousContainerList = PreviousContainerList
connectionsLoad.PreviousConnectionList = PreviousConnectionList
connectionsLoad.PreviousContainerList = PreviousContainerList
End If
If Update = True Then
conL.PreviousSelected = LastSelected
If update = True Then
connectionsLoad.PreviousSelected = LastSelected
End If
Tree.Node.ResetTree()
conL.RootTreeNode = Windows.treeForm.tvConnections.Nodes(0)
connectionsLoad.RootTreeNode = Windows.treeForm.tvConnections.Nodes(0)
conL.UseSQL = My.Settings.UseSQLServer
conL.SQLHost = My.Settings.SQLHost
conL.SQLDatabaseName = My.Settings.SQLDatabaseName
conL.SQLUsername = My.Settings.SQLUser
conL.SQLPassword = Security.Crypt.Decrypt(My.Settings.SQLPass, App.Info.General.EncryptionKey)
conL.SQLUpdate = Update
connectionsLoad.UseSQL = My.Settings.UseSQLServer
connectionsLoad.SQLHost = My.Settings.SQLHost
connectionsLoad.SQLDatabaseName = My.Settings.SQLDatabaseName
connectionsLoad.SQLUsername = My.Settings.SQLUser
connectionsLoad.SQLPassword = Security.Crypt.Decrypt(My.Settings.SQLPass, Info.General.EncryptionKey)
connectionsLoad.SQLUpdate = update
conL.Load(False)
connectionsLoad.Load(False)
If My.Settings.UseSQLServer = True Then
LastSqlUpdate = Now
Else
If conL.ConnectionFileName = App.Info.Connections.DefaultConnectionsPath & "\" & App.Info.Connections.DefaultConnectionsFile Then
If connectionsLoad.ConnectionFileName = GetDefaultStartupConnectionFileName() Then
My.Settings.LoadConsFromCustomLocation = False
Else
My.Settings.LoadConsFromCustomLocation = True
My.Settings.CustomConsPath = conL.ConnectionFileName
My.Settings.CustomConsPath = connectionsLoad.ConnectionFileName
End If
End If
@@ -1115,20 +1128,26 @@ Namespace App
cTaskDialog.ShowCommandBox(Application.ProductName, My.Language.strLoadFromSqlFailed, My.Language.strLoadFromSqlFailedContent, Misc.GetExceptionMessageRecursive(ex), "", "", commandButtons, False, eSysIcons.Error, Nothing)
Select Case cTaskDialog.CommandButtonResult
Case 0
LoadConnections(WithDialog, Update)
LoadConnections(withDialog, update)
Return
Case 1
My.Settings.UseSQLServer = False
LoadConnections(True, Update)
LoadConnections(True, update)
Return
Case Else
Application.Exit()
Return
End Select
Else
MessageCollector.AddExceptionMessage(String.Format(My.Language.strConnectionsFileCouldNotBeLoaded, conL.ConnectionFileName), ex)
If Not conL.ConnectionFileName = GetStartupConnectionFileName() Then
LoadConnections(WithDialog, Update)
If TypeOf ex Is FileNotFoundException And Not withDialog Then
MessageCollector.AddExceptionMessage(String.Format(My.Language.strConnectionsFileCouldNotBeLoadedNew, connectionsLoad.ConnectionFileName), ex, MessageClass.InformationMsg)
NewConnections(connectionsLoad.ConnectionFileName)
Return
End If
MessageCollector.AddExceptionMessage(String.Format(My.Language.strConnectionsFileCouldNotBeLoaded, connectionsLoad.ConnectionFileName), ex)
If Not connectionsLoad.ConnectionFileName = GetStartupConnectionFileName() Then
LoadConnections(withDialog, update)
Return
Else
MsgBox(String.Format(My.Language.strErrorStartupConnectionFileLoad, vbNewLine, Application.ProductName, GetStartupConnectionFileName(), Misc.GetExceptionMessageRecursive(ex)), MsgBoxStyle.OkOnly + MsgBoxStyle.Critical)
@@ -1148,7 +1167,7 @@ Namespace App
File.Copy(fileName, backupFileName)
PruneBackupFiles(fileName)
Catch ex As Exception
MessageCollector.AddMessage(MessageClass.WarningMsg, My.Language.strConnectionsFileBackupFailed & vbNewLine & vbNewLine & ex.Message)
MessageCollector.AddExceptionMessage(My.Language.strConnectionsFileBackupFailed, ex, MessageClass.WarningMsg)
Throw
End Try
End Sub
@@ -1172,26 +1191,23 @@ Namespace App
Next
End Sub
Protected Shared Function GetStartupConnectionFileName() As String
Dim fileName As New String("")
If My.Settings.LoadConsFromCustomLocation = False Then
Dim oldPath As String = GetFolderPath(SpecialFolder.LocalApplicationData) & "\" & My.Application.Info.ProductName & "\" & App.Info.Connections.DefaultConnectionsFile
Dim newPath As String = App.Info.Connections.DefaultConnectionsPath & "\" & App.Info.Connections.DefaultConnectionsFile
Public Shared Function GetDefaultStartupConnectionFileName() As String
Dim newPath As String = App.Info.Connections.DefaultConnectionsPath & "\" & Info.Connections.DefaultConnectionsFile
#If Not PORTABLE Then
If File.Exists(oldPath) Then
fileName = oldPath
Else
fileName = newPath
End If
#Else
fileName = newPath
#End If
Else
fileName = My.Settings.CustomConsPath
Dim oldPath As String = GetFolderPath(SpecialFolder.LocalApplicationData) & "\" & My.Application.Info.ProductName & "\" & Info.Connections.DefaultConnectionsFile
If File.Exists(oldPath) Then
Return oldPath
End If
#End If
Return newPath
End Function
Return fileName
Public Shared Function GetStartupConnectionFileName() As String
If My.Settings.LoadConsFromCustomLocation = False Then
Return GetDefaultStartupConnectionFileName()
Else
Return My.Settings.CustomConsPath
End If
End Function
Public Shared Sub ImportConnections()
@@ -1476,12 +1492,8 @@ Namespace App
Dim conS As New Config.Connections.Save
If My.Settings.UseSQLServer = False Then
If My.Settings.LoadConsFromCustomLocation = False Then
conS.ConnectionFileName = App.Info.Connections.DefaultConnectionsPath & "\" & App.Info.Connections.DefaultConnectionsFile
Else
conS.ConnectionFileName = My.Settings.CustomConsPath
End If
If Not My.Settings.UseSQLServer Then
conS.ConnectionFileName = GetStartupConnectionFileName()
End If
conS.ConnectionList = ConnectionList
@@ -1550,7 +1562,7 @@ Namespace App
Else
connectionsSave.SaveFormat = Config.Connections.Save.Format.mRXML
If connectionsSave.ConnectionFileName = Info.Connections.DefaultConnectionsPath & "\" & Info.Connections.DefaultConnectionsFile Then
If connectionsSave.ConnectionFileName = GetDefaultStartupConnectionFileName() Then
My.Settings.LoadConsFromCustomLocation = False
Else
My.Settings.LoadConsFromCustomLocation = True

View File

@@ -19,7 +19,7 @@ Namespace Config
Private sqlQuery As SqlCommand
Private sqlRd As SqlDataReader
Private selNode As TreeNode
Private _selectedTreeNode As TreeNode
#End Region
#Region "Public Properties"
@@ -103,25 +103,9 @@ Namespace Config
End Set
End Property
Private _RootTreeNode As TreeNode
Public Property RootTreeNode() As TreeNode
Get
Return Me._RootTreeNode
End Get
Set(ByVal value As TreeNode)
Me._RootTreeNode = value
End Set
End Property
Private _ConnectionList As Connection.List
Public Property ConnectionList() As Connection.List
Get
Return Me._ConnectionList
End Get
Set(ByVal value As Connection.List)
Me._ConnectionList = value
End Set
End Property
Private _ContainerList As Container.List
Public Property ContainerList() As Container.List
@@ -166,7 +150,7 @@ Namespace Config
If import = False Then
SetMainFormText(ConnectionFileName)
PuttySessions.AddSessionsToTree()
Putty.Sessions.AddSessionsToTree()
End If
End Sub
#End Region
@@ -181,7 +165,7 @@ Namespace Config
End If
Try
App.Runtime.IsConnectionsFileLoaded = False
IsConnectionsFileLoaded = False
If _SQLUsername <> "" Then
sqlCon = New SqlConnection("Data Source=" & _SQLHost & ";Initial Catalog=" & _SQLDatabaseName & ";User Id=" & _SQLUsername & ";Password=" & _SQLPassword)
@@ -197,7 +181,7 @@ Namespace Config
sqlRd.Read()
If sqlRd.HasRows = False Then
App.Runtime.SaveConnections()
SaveConnections()
sqlQuery = New SqlCommand("SELECT * FROM tblRoot", sqlCon)
sqlRd = sqlQuery.ExecuteReader(CommandBehavior.CloseConnection)
@@ -212,40 +196,33 @@ Namespace Config
Throw New Exception(String.Format("Incompatible database schema (schema version {0}).", confVersion))
End If
Dim rootNode As TreeNode
rootNode = New TreeNode(sqlRd.Item("Name"))
RootTreeNode.Name = sqlRd.Item("Name")
Dim rInfo As New Root.Info(Root.Info.RootType.Connection)
rInfo.Name = rootNode.Text
rInfo.TreeNode = rootNode
Dim rootInfo As New Root.Info(Root.Info.RootType.Connection)
rootInfo.Name = RootTreeNode.Name
rootInfo.TreeNode = RootTreeNode
rootNode.Tag = rInfo
rootNode.ImageIndex = Images.Enums.TreeImage.Root
rootNode.SelectedImageIndex = Images.Enums.TreeImage.Root
RootTreeNode.Tag = rootInfo
RootTreeNode.ImageIndex = Images.Enums.TreeImage.Root
RootTreeNode.SelectedImageIndex = Images.Enums.TreeImage.Root
If Security.Crypt.Decrypt(sqlRd.Item("Protected"), pW) <> "ThisIsNotProtected" Then
If Authenticate(sqlRd.Item("Protected"), False, rInfo) = False Then
If Authenticate(sqlRd.Item("Protected"), False, rootInfo) = False Then
My.Settings.LoadConsFromCustomLocation = False
My.Settings.CustomConsPath = ""
rootNode.Remove()
RootTreeNode.Remove()
Exit Sub
End If
End If
'Me._RootTreeNode.Text = rootNode.Text
'Me._RootTreeNode.Tag = rootNode.Tag
'Me._RootTreeNode.ImageIndex = Images.Enums.TreeImage.Root
'Me._RootTreeNode.SelectedImageIndex = Images.Enums.TreeImage.Root
sqlRd.Close()
Windows.treeForm.tvConnections.BeginUpdate()
' SECTION 3. Populate the TreeView with the DOM nodes.
AddNodesFromSQL(rootNode)
'AddNodeFromXml(xDom.DocumentElement, Me._RootTreeNode)
AddNodesFromSQL(RootTreeNode)
rootNode.Expand()
RootTreeNode.Expand()
'expand containers
For Each contI As Container.Info In Me._ContainerList
@@ -258,21 +235,16 @@ Namespace Config
'open connections from last mremote session
If My.Settings.OpenConsFromLastSession = True And My.Settings.NoReconnect = False Then
For Each conI As Connection.Info In Me._ConnectionList
For Each conI As Connection.Info In ConnectionList
If conI.PleaseConnect = True Then
App.Runtime.OpenConnection(conI)
OpenConnection(conI)
End If
Next
End If
'Tree.Node.TreeView.Nodes.Clear()
'Tree.Node.TreeView.Nodes.Add(rootNode)
AddNodeToTree(rootNode)
SetSelectedNode(selNode)
App.Runtime.IsConnectionsFileLoaded = True
'App.Runtime.Windows.treeForm.InitialRefresh()
IsConnectionsFileLoaded = True
Windows.treeForm.InitialRefresh()
SetSelectedNode(_selectedTreeNode)
Catch ex As Exception
Throw
Finally
@@ -282,29 +254,15 @@ Namespace Config
End Try
End Sub
Private Delegate Sub AddNodeToTreeCB(ByVal TreeNode As TreeNode)
Private Sub AddNodeToTree(ByVal TreeNode As TreeNode)
If Tree.Node.TreeView.InvokeRequired Then
Dim d As New AddNodeToTreeCB(AddressOf AddNodeToTree)
App.Runtime.Windows.treeForm.Invoke(d, New Object() {TreeNode})
Else
App.Runtime.Windows.treeForm.tvConnections.Nodes.Clear()
App.Runtime.Windows.treeForm.tvConnections.Nodes.Add(TreeNode)
App.Runtime.Windows.treeForm.InitialRefresh()
Private Delegate Sub SetSelectedNodeDelegate(ByVal treeNode As TreeNode)
Private Shared Sub SetSelectedNode(ByVal treeNode As TreeNode)
If Tree.Node.TreeView IsNot Nothing AndAlso Tree.Node.TreeView.InvokeRequired Then
Windows.treeForm.Invoke(New SetSelectedNodeDelegate(AddressOf SetSelectedNode), New Object() {treeNode})
Return
End If
Windows.treeForm.tvConnections.SelectedNode = treeNode
End Sub
Private Delegate Sub SetSelectedNodeCB(ByVal TreeNode As TreeNode)
Private Sub SetSelectedNode(ByVal TreeNode As TreeNode)
If Tree.Node.TreeView.InvokeRequired Then
Dim d As New SetSelectedNodeCB(AddressOf SetSelectedNode)
App.Runtime.Windows.treeForm.Invoke(d, New Object() {TreeNode})
Else
App.Runtime.Windows.treeForm.tvConnections.SelectedNode = TreeNode
End If
End Sub
Private Sub AddNodesFromSQL(ByVal baseNode As TreeNode)
Try
sqlCon.Open()
@@ -352,7 +310,7 @@ Namespace Config
End If
If conI.ConstantID = _PreviousSelected Then
selNode = tNode
_selectedTreeNode = tNode
End If
Else
tNode.ImageIndex = Images.Enums.TreeImage.ConnectionClosed
@@ -385,7 +343,7 @@ Namespace Config
End If
If conI.ConstantID = _PreviousSelected Then
selNode = tNode
_selectedTreeNode = tNode
End If
Else
If sqlRd.Item("Expanded") = True Then
@@ -669,28 +627,27 @@ Namespace Config
End If
' SECTION 2. Initialize the treeview control.
Dim rootNode As TreeNode
Dim rootNodeName As String = ""
If xDom.DocumentElement.HasAttribute("Name") Then rootNodeName = xDom.DocumentElement.Attributes("Name").Value.Trim()
If Not String.IsNullOrEmpty(rootNodeName) Then
rootNode = New TreeNode(rootNodeName)
RootTreeNode.Name = rootNodeName
Else
rootNode = New TreeNode(xDom.DocumentElement.Name)
RootTreeNode.Name = xDom.DocumentElement.Name
End If
RootTreeNode.Text = RootTreeNode.Name
Dim rInfo As New Root.Info(Root.Info.RootType.Connection)
rInfo.Name = rootNode.Text
rInfo.TreeNode = rootNode
Dim rootInfo As New Root.Info(Root.Info.RootType.Connection)
rootInfo.Name = RootTreeNode.Name
rootInfo.TreeNode = RootTreeNode
rootNode.Tag = rInfo
RootTreeNode.Tag = rootInfo
If Me.confVersion > 1.3 Then '1.4
If Security.Crypt.Decrypt(xDom.DocumentElement.Attributes("Protected").Value, pW) <> "ThisIsNotProtected" Then
If Authenticate(xDom.DocumentElement.Attributes("Protected").Value, False, rInfo) = False Then
If Authenticate(xDom.DocumentElement.Attributes("Protected").Value, False, rootInfo) = False Then
My.Settings.LoadConsFromCustomLocation = False
My.Settings.CustomConsPath = ""
_RootTreeNode.Remove()
RootTreeNode.Remove()
Exit Sub
End If
End If
@@ -709,18 +666,16 @@ Namespace Config
End If
If Not isExportFile Then
_RootTreeNode.Text = rootNode.Text
_RootTreeNode.Tag = rootNode.Tag
_RootTreeNode.ImageIndex = Images.Enums.TreeImage.Root
_RootTreeNode.SelectedImageIndex = Images.Enums.TreeImage.Root
RootTreeNode.ImageIndex = Images.Enums.TreeImage.Root
RootTreeNode.SelectedImageIndex = Images.Enums.TreeImage.Root
End If
Windows.treeForm.tvConnections.BeginUpdate()
' SECTION 3. Populate the TreeView with the DOM nodes.
AddNodeFromXml(xDom.DocumentElement, _RootTreeNode)
AddNodeFromXml(xDom.DocumentElement, RootTreeNode)
Me._RootTreeNode.Expand()
RootTreeNode.Expand()
'expand containers
For Each contI As Container.Info In Me._ContainerList
@@ -733,18 +688,18 @@ Namespace Config
'open connections from last mremote session
If My.Settings.OpenConsFromLastSession = True And My.Settings.NoReconnect = False Then
For Each conI As Connection.Info In Me._ConnectionList
For Each conI As Connection.Info In _ConnectionList
If conI.PleaseConnect = True Then
App.Runtime.OpenConnection(conI)
OpenConnection(conI)
End If
Next
End If
Me._RootTreeNode.EnsureVisible()
RootTreeNode.EnsureVisible()
App.Runtime.IsConnectionsFileLoaded = True
App.Runtime.Windows.treeForm.InitialRefresh()
IsConnectionsFileLoaded = True
Windows.treeForm.InitialRefresh()
SetSelectedNode(RootTreeNode)
Catch ex As Exception
App.Runtime.IsConnectionsFileLoaded = False
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strLoadFromXmlFailed & vbNewLine & ex.Message & vbNewLine & ex.StackTrace, True)
@@ -760,7 +715,7 @@ Namespace Config
If parentXmlNode.HasChildNodes() Then
For Each xmlNode As XmlNode In parentXmlNode.ChildNodes
Dim treeNode As TreeNode = New TreeNode(xmlNode.Attributes("Name").Value)
parentTreeNode.Nodes.Add(TreeNode)
parentTreeNode.Nodes.Add(treeNode)
If Tree.Node.GetNodeTypeFromString(xmlNode.Attributes("Type").Value) = Tree.Node.Type.Connection Then 'connection info
Dim connectionInfo As Connection.Info = GetConnectionInfoFromXml(xmlNode)

View File

@@ -0,0 +1,99 @@
Imports mRemoteNG.My
Namespace Config.Putty
Public MustInherit Class Provider
#Region "Public Methods"
Private _rootTreeNode As TreeNode
Public ReadOnly Property RootTreeNode As TreeNode
Get
If _rootTreeNode Is Nothing Then _rootTreeNode = CreateRootTreeNode()
Return _rootTreeNode
End Get
End Property
Private _rootInfo As Root.PuttySessions.Info
Public ReadOnly Property RootInfo() As Root.PuttySessions.Info
Get
If _rootInfo Is Nothing Then _rootInfo = CreateRootInfo()
Return _rootInfo
End Get
End Property
Public MustOverride Function GetSessionNames(Optional ByVal raw As Boolean = False) As String()
Public MustOverride Function GetSession(ByVal sessionName As String) As Connection.PuttySession.Info
Public Overridable Function GetSessions() As Connection.PuttySession.Info()
Dim sessionList As New List(Of Connection.PuttySession.Info)
Dim sessionInfo As Connection.Info
For Each sessionName As String In GetSessionNames(True)
sessionInfo = GetSession(sessionName)
If sessionInfo Is Nothing OrElse String.IsNullOrEmpty(sessionInfo.Hostname) Then Continue For
sessionList.Add(sessionInfo)
Next
Return sessionList.ToArray()
End Function
Public Overridable Sub StartWatcher()
End Sub
Public Overridable Sub StopWatcher()
End Sub
#End Region
#Region "Public Events"
Public Event SessionChanged(ByVal sender As Object, ByVal e As SessionChangedEventArgs)
#End Region
#Region "Public Classes"
Public Class SessionChangedEventArgs
Inherits EventArgs
End Class
#End Region
#Region "Protected Methods"
Private Delegate Function CreateRootTreeNodeDelegate() As TreeNode
Protected Overridable Function CreateRootTreeNode() As TreeNode
Dim treeView As TreeView = Tree.Node.TreeView
If treeView Is Nothing Then Return Nothing
If treeView.InvokeRequired Then
Return treeView.Invoke(New CreateRootTreeNodeDelegate(AddressOf CreateRootTreeNode))
End If
Dim newTreeNode As New TreeNode
RootInfo.TreeNode = newTreeNode
newTreeNode.Name = _rootInfo.Name
newTreeNode.Text = _rootInfo.Name
newTreeNode.Tag = _rootInfo
newTreeNode.ImageIndex = Images.Enums.TreeImage.PuttySessions
newTreeNode.SelectedImageIndex = Images.Enums.TreeImage.PuttySessions
Return newTreeNode
End Function
Protected Overridable Function CreateRootInfo() As Root.PuttySessions.Info
Dim newRootInfo As New Root.PuttySessions.Info
If String.IsNullOrEmpty(My.Settings.PuttySavedSessionsName) Then
newRootInfo.Name = Language.strPuttySavedSessionsRootName
Else
newRootInfo.Name = My.Settings.PuttySavedSessionsName
End If
If String.IsNullOrEmpty(My.Settings.PuttySavedSessionsPanel) Then
newRootInfo.Panel = Language.strGeneral
Else
newRootInfo.Panel = My.Settings.PuttySavedSessionsPanel
End If
Return newRootInfo
End Function
Protected Overridable Sub OnSessionChanged(ByVal e As SessionChangedEventArgs)
RaiseEvent SessionChanged(Me, New SessionChangedEventArgs())
End Sub
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,121 @@
Imports System.Management
Imports mRemoteNG.App
Imports mRemoteNG.Messages
Imports Microsoft.Win32
Imports mRemoteNG.Connection.Protocol
Imports System.Security.Principal
Namespace Config.Putty
Public Class RegistryProvider
Inherits Provider
#Region "Public Methods"
Public Overrides Function GetSessionNames(Optional ByVal raw As Boolean = False) As String()
Dim sessionsKey As RegistryKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey)
If sessionsKey Is Nothing Then Return New String() {}
Dim sessionNames As New List(Of String)
For Each sessionName As String In sessionsKey.GetSubKeyNames()
If raw Then
sessionNames.Add(sessionName)
Else
sessionNames.Add(Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B")))
End If
Next
If raw Then
If Not sessionNames.Contains("Default%20Settings") Then ' Do not localize
sessionNames.Insert(0, "Default%20Settings")
End If
Else
If Not sessionNames.Contains("Default Settings") Then
sessionNames.Insert(0, "Default Settings")
End If
End If
Return sessionNames.ToArray()
End Function
Public Overrides Function GetSession(ByVal sessionName As String) As Connection.PuttySession.Info
Dim sessionsKey As RegistryKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey)
If sessionsKey Is Nothing Then Return Nothing
Dim sessionKey As RegistryKey = sessionsKey.OpenSubKey(sessionName)
If sessionKey Is Nothing Then Return Nothing
sessionName = Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B"))
Dim sessionInfo As New Connection.PuttySession.Info
With sessionInfo
.PuttySession = sessionName
.Name = sessionName
.Hostname = sessionKey.GetValue("HostName")
.Username = sessionKey.GetValue("UserName")
Dim protocol As String = sessionKey.GetValue("Protocol")
If protocol Is Nothing Then protocol = "ssh"
Select Case protocol.ToLowerInvariant()
Case "raw"
.Protocol = Protocols.RAW
Case "rlogin"
.Protocol = Protocols.Rlogin
Case "serial"
Return Nothing
Case "ssh"
Dim sshVersionObject As Object = sessionKey.GetValue("SshProt")
If sshVersionObject IsNot Nothing Then
Dim sshVersion As Integer = CType(sshVersionObject, Integer)
If sshVersion >= 2 Then
.Protocol = Protocols.SSH2
Else
.Protocol = Protocols.SSH1
End If
Else
.Protocol = Protocols.SSH2
End If
Case "telnet"
.Protocol = Protocols.Telnet
Case Else
Return Nothing
End Select
.Port = sessionKey.GetValue("PortNumber")
End With
Return sessionInfo
End Function
Public Overrides 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
Runtime.MessageCollector.AddExceptionMessage("PuttySessions.Watcher.StartWatching() failed.", ex, MessageClass.WarningMsg, True)
End Try
End Sub
Public Overrides Sub StopWatcher()
If _eventWatcher Is Nothing Then Return
_eventWatcher.Stop()
_eventWatcher.Dispose()
_eventWatcher = Nothing
End Sub
#End Region
#Region "Private Fields"
Private Const PuttySessionsKey As String = "Software\SimonTatham\PuTTY\Sessions"
Private Shared _eventWatcher As ManagementEventWatcher
#End Region
#Region "Private Methods"
Private Sub OnManagementEventArrived(ByVal sender As Object, ByVal e As EventArrivedEventArgs)
OnSessionChanged(New SessionChangedEventArgs())
End Sub
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,168 @@
Imports System.ComponentModel
Imports mRemoteNG.Tools
Namespace Config.Putty
Public Class Sessions
#Region "Public Methods"
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
For Each provider As Provider In Providers
Dim rootTreeNode As TreeNode = provider.RootTreeNode
Dim inUpdate As Boolean = False
Dim savedSessions As New List(Of Connection.Info)(provider.GetSessions())
If Not IsProviderEnabled(provider) Or savedSessions Is Nothing OrElse savedSessions.Count = 0 Then
If rootTreeNode IsNot Nothing AndAlso treeView.Nodes.Contains(rootTreeNode) Then
treeView.BeginUpdate()
treeView.Nodes.Remove(rootTreeNode)
treeView.EndUpdate()
End If
Continue For
End If
If Not treeView.Nodes.Contains(rootTreeNode) Then
If Not inUpdate Then
treeView.BeginUpdate()
inUpdate = True
End If
treeView.Nodes.Add(rootTreeNode)
End If
Dim newTreeNodes As New List(Of TreeNode)
For Each sessionInfo As Connection.PuttySession.Info In savedSessions
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 = provider.RootInfo
sessionInfo.TreeNode = treeNode
sessionInfo.Inherit.TurnOffInheritanceCompletely()
treeNode.Tag = sessionInfo
If isNewNode Then newTreeNodes.Add(treeNode)
Next
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
Next
End Sub
Public Shared Sub StartWatcher()
For Each provider As Provider In Providers
provider.StartWatcher()
AddHandler provider.SessionChanged, AddressOf SessionChanged
Next
End Sub
Public Shared Sub StopWatcher()
For Each provider As Provider In Providers
provider.StopWatcher()
RemoveHandler provider.SessionChanged, AddressOf SessionChanged
Next
End Sub
Public Shared Sub SessionChanged(ByVal sender As Object, ByVal e As Provider.SessionChangedEventArgs)
AddSessionsToTree()
End Sub
#End Region
#Region "Private Methods"
Private Shared _providers As List(Of Provider)
Private Shared ReadOnly Property Providers() As List(Of Provider)
Get
If _providers Is Nothing OrElse _providers.Count = 0 Then AddProviders()
Return _providers
End Get
End Property
Private Shared Sub AddProviders()
_providers = New List(Of Provider)()
_providers.Add(New RegistryProvider())
_providers.Add(New XmingProvider())
End Sub
Private Shared Function GetSessionNames(Optional ByVal raw As Boolean = False) As String()
Dim sessionNames As New List(Of String)
For Each provider As Provider In Providers
If Not IsProviderEnabled(provider) Then Continue For
sessionNames.AddRange(provider.GetSessionNames(raw))
Next
Return sessionNames.ToArray()
End Function
Private Shared Function IsProviderEnabled(ByVal provider As Provider) As Boolean
Dim enabled As Boolean = True
Select Case PuttyTypeDetector.GetPuttyType()
Case PuttyTypeDetector.PuttyType.Xming
If TypeOf (provider) Is RegistryProvider Then enabled = False
Case Else
If TypeOf (provider) Is XmingProvider Then enabled = False
End Select
Return enabled
End Function
#End Region
#Region "Public Classes"
Public Class SessionList
Inherits StringConverter
Public Shared ReadOnly Property Names() As String()
Get
Return GetSessionNames()
End Get
End Property
Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection
Return New StandardValuesCollection(Names)
End Function
Public Overloads Overrides Function GetStandardValuesExclusive(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
Return True
End Function
Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As ITypeDescriptorContext) As Boolean
Return True
End Function
End Class
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,259 @@
Imports System.IO
Imports mRemoteNG.App
Imports mRemoteNG.Messages
Imports mRemoteNG.Connection.Protocol
Imports System.Text.RegularExpressions
Namespace Config.Putty
Public Class XmingProvider
Inherits Provider
#Region "Public Methods"
Public Overrides Function GetSessionNames(Optional ByVal raw As Boolean = False) As String()
Dim sessionsFolderPath As String = GetSessionsFolderPath()
If Not Directory.Exists(sessionsFolderPath) Then Return New String() {}
Dim sessionNames As New List(Of String)
For Each sessionName As String In Directory.GetFiles(sessionsFolderPath)
sessionName = Path.GetFileName(sessionName)
If raw Then
sessionNames.Add(sessionName)
Else
sessionNames.Add(Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B")))
End If
Next
If raw Then
If Not sessionNames.Contains("Default%20Settings") Then ' Do not localize
sessionNames.Insert(0, "Default%20Settings")
End If
Else
If Not sessionNames.Contains("Default Settings") Then
sessionNames.Insert(0, "Default Settings")
End If
End If
Dim registrySessionNames As New List(Of String)
For Each sessionName As String In RegistryProvider.GetSessionNames(raw)
registrySessionNames.Add(String.Format(RegistrySessionNameFormat, sessionName))
Next
sessionNames.AddRange(registrySessionNames)
sessionNames.Sort()
Return sessionNames.ToArray()
End Function
Public Overrides Function GetSession(ByVal sessionName As String) As Connection.PuttySession.Info
Dim registrySessionName As String = GetRegistrySessionName(sessionName)
If Not String.IsNullOrEmpty(registrySessionName) Then
Return ModifyRegistrySessionInfo(RegistryProvider.GetSession(registrySessionName))
End If
Dim sessionsFolderPath As String = GetSessionsFolderPath()
If Not Directory.Exists(sessionsFolderPath) Then Return Nothing
Dim sessionFile As String = Path.Combine(sessionsFolderPath, sessionName)
If Not File.Exists(sessionFile) Then Return Nothing
sessionName = Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B"))
Dim sessionFileReader As New SessionFileReader(sessionFile)
Dim sessionInfo As New Connection.PuttySession.Info
With sessionInfo
.PuttySession = sessionName
.Name = sessionName
.Hostname = sessionFileReader.GetValue("HostName")
.Username = sessionFileReader.GetValue("UserName")
Dim protocol As String = sessionFileReader.GetValue("Protocol")
If protocol Is Nothing Then protocol = "ssh"
Select Case protocol.ToLowerInvariant()
Case "raw"
.Protocol = Protocols.RAW
Case "rlogin"
.Protocol = Protocols.Rlogin
Case "serial"
Return Nothing
Case "ssh"
Dim sshVersionObject As Object = sessionFileReader.GetValue("SshProt")
If sshVersionObject IsNot Nothing Then
Dim sshVersion As Integer = CType(sshVersionObject, Integer)
If sshVersion >= 2 Then
.Protocol = Protocols.SSH2
Else
.Protocol = Protocols.SSH1
End If
Else
.Protocol = Protocols.SSH2
End If
Case "telnet"
.Protocol = Protocols.Telnet
Case Else
Return Nothing
End Select
.Port = sessionFileReader.GetValue("PortNumber")
End With
Return sessionInfo
End Function
Public Overrides Sub StartWatcher()
RegistryProvider.StartWatcher()
AddHandler RegistryProvider.SessionChanged, AddressOf OnRegistrySessionChanged
If _eventWatcher IsNot Nothing Then Return
Try
_eventWatcher = New FileSystemWatcher(GetSessionsFolderPath())
_eventWatcher.NotifyFilter = (NotifyFilters.FileName Or NotifyFilters.LastWrite)
AddHandler _eventWatcher.Changed, AddressOf OnFileSystemEventArrived
AddHandler _eventWatcher.Created, AddressOf OnFileSystemEventArrived
AddHandler _eventWatcher.Deleted, AddressOf OnFileSystemEventArrived
AddHandler _eventWatcher.Renamed, AddressOf OnFileSystemEventArrived
_eventWatcher.EnableRaisingEvents = True
Catch ex As Exception
Runtime.MessageCollector.AddExceptionMessage("XmingPortablePuttySessions.Watcher.StartWatching() failed.", ex, MessageClass.WarningMsg, True)
End Try
End Sub
Public Overrides Sub StopWatcher()
RegistryProvider.StopWatcher()
RemoveHandler RegistryProvider.SessionChanged, AddressOf OnRegistrySessionChanged
If _eventWatcher Is Nothing Then Return
_eventWatcher.EnableRaisingEvents = False
_eventWatcher.Dispose()
_eventWatcher = Nothing
End Sub
#End Region
#Region "Private Fields"
Private Const RegistrySessionNameFormat As String = "{0} [registry]"
Private Const RegistrySessionNamePattern As String = "(.*)\ \[registry\]"
Private Shared ReadOnly RegistryProvider As New RegistryProvider
Private Shared _eventWatcher As FileSystemWatcher
#End Region
#Region "Private Methods"
Private Shared Function GetPuttyConfPath() As String
Dim puttyPath As String
If My.Settings.UseCustomPuttyPath Then
puttyPath = My.Settings.CustomPuttyPath
Else
puttyPath = Info.General.PuttyPath
End If
Return Path.Combine(Path.GetDirectoryName(puttyPath), "putty.conf")
End Function
Private Shared Function GetSessionsFolderPath() As String
Dim puttyConfPath As String = GetPuttyConfPath()
Dim sessionFileReader As New PuttyConfFileReader(puttyConfPath)
Dim basePath As String = Environment.ExpandEnvironmentVariables(sessionFileReader.GetValue("sshk&sess"))
Return Path.Combine(basePath, "sessions")
End Function
Private Shared Function GetRegistrySessionName(ByVal sessionName As String) As String
Dim regex As New Regex(RegistrySessionNamePattern)
Dim matches As MatchCollection = regex.Matches(sessionName)
If matches.Count < 1 Then Return String.Empty
Dim groups As GroupCollection = matches(0).Groups
If groups.Count < 1 Then Return String.Empty ' This should always include at least one item, but check anyway
Return groups(1).Value
End Function
Private Shared Function ModifyRegistrySessionInfo(ByVal sessionInfo As Connection.PuttySession.Info) As Connection.PuttySession.Info
sessionInfo.Name = String.Format(RegistrySessionNameFormat, sessionInfo.Name)
sessionInfo.PuttySession = String.Format(RegistrySessionNameFormat, sessionInfo.PuttySession)
Return sessionInfo
End Function
Private Sub OnFileSystemEventArrived(ByVal sender As Object, ByVal e As FileSystemEventArgs)
OnSessionChanged(New SessionChangedEventArgs())
End Sub
Private Sub OnRegistrySessionChanged(ByVal sender As Object, ByVal e As SessionChangedEventArgs)
OnSessionChanged(New SessionChangedEventArgs())
End Sub
#End Region
#Region "Private Classes"
Private Class PuttyConfFileReader
Public Sub New(ByVal puttyConfFile As String)
_puttyConfFile = puttyConfFile
End Sub
Private ReadOnly _puttyConfFile As String
Private _configurationLoaded As Boolean = False
Private ReadOnly _configuration As New Dictionary(Of String, String)
Private Sub LoadConfiguration()
_configurationLoaded = True
Try
If Not File.Exists(_puttyConfFile) Then Return
Using streamReader As New StreamReader(_puttyConfFile)
Dim line As String
Do
line = streamReader.ReadLine()
If line Is Nothing Then Exit Do
line = line.Trim()
If line = String.Empty Then Continue Do ' Blank line
If line.Substring(0, 1) = ";" Then Continue Do ' Comment
Dim parts() As String = line.Split(New Char() {"="}, 2)
If parts.Length < 2 Then Continue Do
If _configuration.ContainsKey(parts(0)) Then Continue Do ' As per http://www.straightrunning.com/XmingNotes/portableputty.php only first entry is used
_configuration.Add(parts(0), parts(1))
Loop
End Using
Catch ex As Exception
Runtime.MessageCollector.AddExceptionMessage("PuttyConfFileReader.LoadConfiguration() failed.", ex, MessageClass.ErrorMsg, True)
End Try
End Sub
Public Function GetValue(ByVal setting As String) As String
If Not _configurationLoaded Then LoadConfiguration()
If Not _configuration.ContainsKey(setting) Then Return String.Empty
Return _configuration(setting)
End Function
End Class
Private Class SessionFileReader
Public Sub New(ByVal sessionFile As String)
_sessionFile = sessionFile
End Sub
Private ReadOnly _sessionFile As String
Private _sessionInfoLoaded As Boolean = False
Private ReadOnly _sessionInfo As New Dictionary(Of String, String)
Private Sub LoadSessionInfo()
_sessionInfoLoaded = True
Try
If Not File.Exists(_sessionFile) Then Return
Using streamReader As New StreamReader(_sessionFile)
Dim line As String
Do
line = streamReader.ReadLine()
If line Is Nothing Then Exit Do
Dim parts() As String = line.Split(New Char() {"\"})
If parts.Length < 2 Then Continue Do
_sessionInfo.Add(parts(0), parts(1))
Loop
End Using
Catch ex As Exception
Runtime.MessageCollector.AddExceptionMessage("SessionFileReader.LoadSessionInfo() failed.", ex, MessageClass.ErrorMsg, True)
End Try
End Sub
Public Function GetValue(ByVal setting As String) As String
If Not _sessionInfoLoaded Then LoadSessionInfo()
If Not _sessionInfo.ContainsKey(setting) Then Return String.Empty
Return _sessionInfo(setting)
End Function
End Class
#End Region
End Class
End Namespace

View File

@@ -1,243 +0,0 @@
Imports System.ComponentModel
Imports System.Management
Imports mRemoteNG.Messages
Imports Microsoft.Win32
Imports mRemoteNG.Connection.Protocol
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
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
puttyRootInfo.Name = Language.strPuttySavedSessionsRootName
Else
puttyRootInfo.Name = My.Settings.PuttySavedSessionsName
End If
If String.IsNullOrEmpty(My.Settings.PuttySavedSessionsPanel) Then
puttyRootInfo.Panel = Language.strGeneral
Else
puttyRootInfo.Panel = My.Settings.PuttySavedSessionsPanel
End If
Dim inUpdate As Boolean = False
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
End If
If Not treeView.Nodes.Contains(_rootTreeNode) Then
If Not inUpdate Then
treeView.BeginUpdate()
inUpdate = True
End If
treeView.Nodes.Add(_rootTreeNode)
End If
puttyRootInfo.TreeNode = _rootTreeNode
Dim newTreeNodes As New List(Of TreeNode)
For Each sessionInfo As Connection.PuttySession.Info In savedSessions
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 = treeNode
sessionInfo.Inherit.TurnOffInheritanceCompletely()
treeNode.Tag = sessionInfo
If isNewNode Then newTreeNodes.Add(treeNode)
Next
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()
Dim sessionsKey As RegistryKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey)
If sessionsKey Is Nothing Then Return New String() {}
Dim sessionNames As New List(Of String)
For Each sessionName As String In sessionsKey.GetSubKeyNames()
If raw Then
sessionNames.Add(sessionName)
Else
sessionNames.Add(Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B")))
End If
Next
If raw Then
If Not sessionNames.Contains("Default%20Settings") Then ' Do not localize
sessionNames.Insert(0, "Default%20Settings")
End If
Else
If Not sessionNames.Contains("Default Settings") Then
sessionNames.Insert(0, "Default Settings")
End If
End If
Return sessionNames.ToArray()
End Function
Protected Shared Function LoadSessions() As Connection.PuttySession.Info()
Dim sessionList As New List(Of Connection.PuttySession.Info)
Dim sessionInfo As Connection.Info
For Each sessionName As String In GetSessionNames(True)
sessionInfo = SessionToConnectionInfo(sessionName)
If sessionInfo Is Nothing OrElse String.IsNullOrEmpty(sessionInfo.Hostname) Then Continue For
sessionList.Add(sessionInfo)
Next
Return sessionList.ToArray()
End Function
Protected Shared Function SessionToConnectionInfo(ByVal sessionName As String) As Connection.PuttySession.Info
Dim sessionsKey As RegistryKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey)
If sessionsKey Is Nothing Then Return Nothing
Dim sessionKey As RegistryKey = sessionsKey.OpenSubKey(sessionName)
If sessionKey Is Nothing Then Return Nothing
sessionName = Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B"))
Dim sessionInfo As New Connection.PuttySession.Info
With sessionInfo
.PuttySession = sessionName
.Name = sessionName
.Hostname = sessionKey.GetValue("HostName")
.Username = sessionKey.GetValue("UserName")
Dim protocol As String = sessionKey.GetValue("Protocol")
If protocol Is Nothing Then protocol = "ssh"
Select Case protocol.ToLowerInvariant()
Case "raw"
.Protocol = Protocols.RAW
Case "rlogin"
.Protocol = Protocols.Rlogin
Case "serial"
Return Nothing
Case "ssh"
Dim sshVersionObject As Object = sessionKey.GetValue("SshProt")
If sshVersionObject IsNot Nothing Then
Dim sshVersion As Integer = CType(sshVersionObject, Integer)
If sshVersion >= 2 Then
.Protocol = Protocols.SSH2
Else
.Protocol = Protocols.SSH1
End If
Else
.Protocol = Protocols.SSH2
End If
Case "telnet"
.Protocol = Protocols.Telnet
Case Else
Return Nothing
End Select
.Port = sessionKey.GetValue("PortNumber")
End With
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
Public Shared ReadOnly Property Names() As String()
Get
Return GetSessionNames()
End Get
End Property
Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection
Return New StandardValuesCollection(Names)
End Function
Public Overloads Overrides Function GetStandardValuesExclusive(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
Return True
End Function
Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As ITypeDescriptorContext) As Boolean
Return True
End Function
End Class
End Class
End Namespace

View File

@@ -2,23 +2,24 @@ Imports System.Windows.Forms
Imports System.ComponentModel
Imports mRemoteNG.Tools.LocalizedAttributes
Imports mRemoteNG.App.Runtime
Imports mRemoteNG.Config
Namespace Connection
<DefaultProperty("Name")> _
Public Class Info
#Region "Properties"
#Region "1 Display"
Private _Name As String = My.Language.strNewConnection
Private _name As String = My.Language.strNewConnection
<LocalizedCategory("strCategoryDisplay", 1), _
Browsable(True), _
LocalizedDisplayName("strPropertyNameName"), _
LocalizedDescription("strPropertyDescriptionName")> _
Public Overridable Property Name() As String
Get
Return Me._Name
Return _name
End Get
Set(ByVal value As String)
Me._Name = value
_name = value
End Set
End Property
@@ -282,7 +283,7 @@ Namespace Connection
Browsable(True), _
LocalizedDisplayName("strPropertyNamePuttySession"), _
LocalizedDescription("strPropertyDescriptionPuttySession"), _
TypeConverter(GetType(Config.PuttySessions.SessionList))> _
TypeConverter(GetType(Putty.Sessions.SessionList))> _
Public Overridable Property PuttySession() As String
Get
If Me._Inherit.PuttySession And Me._Parent IsNot Nothing Then
@@ -1531,9 +1532,10 @@ Namespace Connection
#End Region
#Region "Methods"
Public Function Copy() As Connection.Info
Dim newConnectionInfo As Connection.Info = MemberwiseClone()
newConnectionInfo._OpenConnections = New Connection.Protocol.List
Public Function Copy() As Info
Dim newConnectionInfo As Info = MemberwiseClone()
newConnectionInfo.ConstantID = Tools.Misc.CreateConstantID()
newConnectionInfo._OpenConnections = New Protocol.List
Return newConnectionInfo
End Function
@@ -1605,8 +1607,8 @@ Namespace Connection
End If
End Sub
Public Function Copy() As Connection.Info.Inheritance
Return Me.MemberwiseClone
Public Function Copy() As Inheritance
Return MemberwiseClone()
End Function
Public Sub TurnOnInheritanceCompletely()

View File

@@ -97,7 +97,7 @@ Namespace Connection
Public Overrides Function Connect() As Boolean
Try
_isPuttyNg = IsFilePuttyNg(PuttyPath)
_isPuttyNg = (PuttyTypeDetector.GetPuttyType() = PuttyTypeDetector.PuttyType.PuttyNg)
PuttyProcess = New Process
With PuttyProcess.StartInfo
@@ -237,18 +237,6 @@ Namespace Connection
End Sub
#End Region
#Region "Public Shared Methods"
Public Shared Function IsFilePuttyNg(file As String) As Boolean
Dim isPuttyNg As Boolean
Try
isPuttyNg = FileVersionInfo.GetVersionInfo(file).InternalName.Contains("PuTTYNG")
Catch
isPuttyNg = False
End Try
Return isPuttyNg
End Function
#End Region
#Region "Enums"
Public Enum Putty_Protocol
ssh = 0

View File

@@ -638,77 +638,91 @@ Namespace Connection
#Region "Terminal Sessions"
Public Class TerminalSessions
Dim oWTSCOM As New WTSCOM
Dim oWTSSessions As New WTSSessions
Dim oWTSSession As New WTSSession
Public ServerHandle As Long
Private ReadOnly _wtsCom As WTSCOM
Public Function OpenConnection(ByVal SrvName As String) As Boolean
Public Sub New()
Try
ServerHandle = oWTSCOM.WTSOpenServer(SrvName)
If ServerHandle <> 0 Then
Return True
End If
_wtsCom = New WTSCOM
Catch ex As Exception
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strRdpOpenConnectionFailed & vbNewLine & ex.Message, True)
End Try
Return False
End Function
Public Sub CloseConnection(ByVal SrvHandle As Long)
Try
oWTSCOM.WTSCloseServer(ServerHandle)
ServerHandle = 0
Catch ex As Exception
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strRdpCloseConnectionFailed & vbNewLine & ex.Message, True)
MessageCollector.AddExceptionMessage("TerminalSessions.New() failed.", ex, MessageClass.ErrorMsg, True)
End Try
End Sub
Public Function GetSessions() As Sessions
Dim colSessions As New Sessions
Public Function OpenConnection(ByVal hostname As String) As Long
If _wtsCom Is Nothing Then Return 0
Try
oWTSSessions = oWTSCOM.WTSEnumerateSessions(ServerHandle)
Return _wtsCom.WTSOpenServer(hostname)
Catch ex As Exception
MessageCollector.AddExceptionMessage(My.Language.strRdpOpenConnectionFailed, ex, MessageClass.ErrorMsg, True)
End Try
End Function
Dim SessionID As Long
Dim SessionUser As String
Dim SessionState As Long
Dim SessionName As String
Public Sub CloseConnection(ByVal serverHandle As Long)
If _wtsCom Is Nothing Then Return
For Each oWTSSession In oWTSSessions
SessionID = oWTSSession.SessionId
SessionUser = oWTSCOM.WTSQuerySessionInformation(ServerHandle, oWTSSession.SessionId, 5) 'WFUsername = 5
SessionState = oWTSSession.State & vbCrLf
SessionName = oWTSSession.WinStationName & vbCrLf
Try
_wtsCom.WTSCloseServer(serverHandle)
Catch ex As Exception
MessageCollector.AddExceptionMessage(My.Language.strRdpCloseConnectionFailed, ex, MessageClass.ErrorMsg, True)
End Try
End Sub
If SessionUser <> "" Then
If SessionState = 0 Then
colSessions.Add(SessionID, My.Language.strActive, SessionUser, SessionName)
Public Function GetSessions(ByVal serverHandle As Long) As SessionsCollection
If _wtsCom Is Nothing Then Return New SessionsCollection()
Dim sessions As New SessionsCollection()
Try
Dim wtsSessions As WTSSessions = _wtsCom.WTSEnumerateSessions(serverHandle)
Dim sessionId As Long
Dim sessionUser As String
Dim sessionState As Long
Dim sessionName As String
For Each wtsSession As WTSSession In wtsSessions
sessionId = wtsSession.SessionId
sessionUser = _wtsCom.WTSQuerySessionInformation(serverHandle, wtsSession.SessionId, 5) ' WFUsername = 5
sessionState = wtsSession.State & vbCrLf
sessionName = wtsSession.WinStationName & vbCrLf
If Not String.IsNullOrEmpty(sessionUser) Then
If sessionState = 0 Then
sessions.Add(sessionId, My.Language.strActive, sessionUser, sessionName)
Else
colSessions.Add(SessionID, My.Language.strInactive, SessionUser, SessionName)
sessions.Add(sessionId, My.Language.strInactive, sessionUser, sessionName)
End If
End If
Next
Catch ex As Exception
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strRdpGetSessionsFailed & vbNewLine & ex.Message, True)
MessageCollector.AddExceptionMessage(My.Language.strRdpGetSessionsFailed, ex, MessageClass.ErrorMsg, True)
End Try
Return colSessions
Return sessions
End Function
Public Function KillSession(ByVal SessionID As Long) As Boolean
Return oWTSCOM.WTSLogoffSession(ServerHandle, SessionID, True)
Public Function KillSession(ByVal serverHandle As Long, ByVal sessionId As Long) As Boolean
If _wtsCom Is Nothing Then Return False
Dim result As Boolean = False
Try
result = _wtsCom.WTSLogoffSession(serverHandle, sessionId, True)
Catch ex As Exception
MessageCollector.AddExceptionMessage("TerminalSessions.KillSession() failed.", ex, MessageClass.ErrorMsg, True)
End Try
Return result
End Function
End Class
Public Class Sessions
Public Class SessionsCollection
Inherits CollectionBase
Default Public ReadOnly Property Items(ByVal Index As Integer) As Session
Default Public ReadOnly Property Items(ByVal index As Integer) As Session
Get
Return CType(List.Item(Index), Session)
Return CType(List.Item(index), Session)
End Get
End Property
@@ -718,23 +732,23 @@ Namespace Connection
End Get
End Property
Public Function Add(ByVal SessionID As Long, ByVal SessionState As String, ByVal SessionUser As String, ByVal SessionName As String) As Session
Dim newSes As New Session
Public Overloads Function Add(ByVal sessionId As Long, ByVal sessionState As String, ByVal sessionUser As String, ByVal sessionName As String) As Session
Dim newSession As New Session
Try
With newSes
.SessionID = SessionID
.SessionState = SessionState
.SessionUser = SessionUser
.SessionName = SessionName
With newSession
.SessionId = sessionId
.SessionState = sessionState
.SessionUser = sessionUser
.SessionName = sessionName
End With
List.Add(newSes)
List.Add(newSession)
Catch ex As Exception
MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, My.Language.strRdpAddSessionFailed & vbNewLine & ex.Message, True)
MessageCollector.AddExceptionMessage(My.Language.strRdpAddSessionFailed, ex, MessageClass.ErrorMsg, True)
End Try
Return newSes
Return newSession
End Function
Public Sub ClearSessions()
@@ -745,45 +759,10 @@ Namespace Connection
Public Class Session
Inherits CollectionBase
Private lngSessionID As Long
Public Property SessionID() As Long
Get
Return lngSessionID
End Get
Set(ByVal Value As Long)
lngSessionID = Value
End Set
End Property
Private lngSessionState As String
Public Property SessionId() As Long
Public Property SessionState() As String
Get
Return lngSessionState
End Get
Set(ByVal Value As String)
lngSessionState = Value
End Set
End Property
Private strSessionUser As String
Public Property SessionUser() As String
Get
Return strSessionUser
End Get
Set(ByVal Value As String)
strSessionUser = Value
End Set
End Property
Private strSessionName As String
Public Property SessionName() As String
Get
Return strSessionName
End Get
Set(ByVal Value As String)
strSessionName = Value
End Set
End Property
End Class
#End Region

View File

@@ -100,6 +100,7 @@ Namespace Connection
#End Region
#Region "IComponent"
<Browsable(False)> _
Public Property Site() As ISite Implements IComponent.Site
Get
Return New PropertyGridCommandSite(Me)

View File

@@ -6,7 +6,6 @@ Namespace Container
<DefaultProperty("Name")> _
Public Class Info
#Region "Properties"
Private _Name As String = "New Container"
<LocalizedCategory("strCategoryDisplay", 1), _
Browsable(True), _
[ReadOnly](False), _
@@ -18,10 +17,10 @@ Namespace Container
Attributes.Container()> _
Public Property Name() As String
Get
Return Me._ConnectionInfo.Name
Return ConnectionInfo.Name
End Get
Set(ByVal value As String)
Me._ConnectionInfo.Name = value
ConnectionInfo.Name = value
End Set
End Property

View File

@@ -71,6 +71,12 @@ Public Class frmMain
Tree.Node.TreeView = Windows.treeForm.tvConnections
If My.Settings.FirstStart And _
Not My.Settings.LoadConsFromCustomLocation And _
Not IO.File.Exists(GetStartupConnectionFileName()) Then
NewConnections(GetStartupConnectionFileName())
End If
'LoadCredentials()
LoadConnections()
If Not IsConnectionsFileLoaded Then
@@ -78,7 +84,7 @@ Public Class frmMain
Return
End If
PuttySessions.StartWatcher()
Putty.Sessions.StartWatcher()
If My.Settings.StartupComponentsCheck Then
Windows.Show(UI.Window.Type.ComponentsCheck)
@@ -211,7 +217,9 @@ Public Class frmMain
End Sub
Private Sub frmMain_Shown(sender As Object, e As EventArgs) Handles Me.Shown
#If Not PORTABLE Then
#If PORTABLE Then
Return
#End If
If Not My.Settings.CheckForUpdatesAsked Then
Dim commandButtons() As String = {My.Language.strAskUpdatesCommandRecommended, My.Language.strAskUpdatesCommandCustom, My.Language.strAskUpdatesCommandAskLater}
cTaskDialog.ShowTaskDialogBox(Me, My.Application.Info.ProductName, My.Language.strAskUpdatesMainInstruction, String.Format(My.Language.strAskUpdatesContent, My.Application.Info.ProductName), "", "", "", "", String.Join("|", commandButtons), eTaskDialogButtons.None, eSysIcons.Question, eSysIcons.Question)
@@ -221,15 +229,17 @@ Public Class frmMain
If cTaskDialog.CommandButtonResult = 1 Then
Windows.ShowUpdatesTab()
End If
Return
End If
If Not My.Settings.CheckForUpdatesOnStartup Then Return
Dim nextUpdateCheck As Date = My.Settings.CheckForUpdatesLastCheck.Add(TimeSpan.FromDays(My.Settings.CheckForUpdatesFrequencyDays))
If My.Settings.UpdatePending Or Date.UtcNow > nextUpdateCheck Then
If Not IsHandleCreated Then CreateHandle() ' Make sure the handle is created so that InvokeRequired returns the correct result
Startup.CheckForUpdate()
Startup.CheckForAnnouncement()
End If
#End If
End Sub
Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

View File

@@ -1927,13 +1927,23 @@ Public Class frmOptions
My.Settings.AutomaticallyGetSessionInfo = Me.chkAutomaticallyGetSessionInfo.Checked
My.Settings.ReconnectOnDisconnect = Me.chkAutomaticReconnect.Checked
My.Settings.SingleInstance = Me.chkSingleInstance.Checked
My.Settings.UseCustomPuttyPath = Me.chkUseCustomPuttyPath.Checked
My.Settings.CustomPuttyPath = Me.txtCustomPuttyPath.Text
If Settings.UseCustomPuttyPath Then
Connection.Protocol.PuttyBase.PuttyPath = Settings.CustomPuttyPath
Else
Connection.Protocol.PuttyBase.PuttyPath = App.Info.General.PuttyPath
Dim puttyPathChanged As Boolean = False
If Not Settings.CustomPuttyPath = txtCustomPuttyPath.Text Then
puttyPathChanged = True
Settings.CustomPuttyPath = txtCustomPuttyPath.Text
End If
If Not Settings.UseCustomPuttyPath = chkUseCustomPuttyPath.Checked Then
puttyPathChanged = True
Settings.UseCustomPuttyPath = chkUseCustomPuttyPath.Checked
End If
If puttyPathChanged Then
If Settings.UseCustomPuttyPath Then
Connection.Protocol.PuttyBase.PuttyPath = Settings.CustomPuttyPath
Else
Connection.Protocol.PuttyBase.PuttyPath = App.Info.General.PuttyPath
End If
Config.Putty.Sessions.AddSessionsToTree()
End If
My.Settings.MaxPuttyWaitTime = Me.numPuttyWaitTime.Value
@@ -1955,11 +1965,7 @@ Public Class frmOptions
ThemeManager.SaveThemes(_themeList)
Settings.ThemeName = ThemeManager.ActiveTheme.Name
If My.Settings.LoadConsFromCustomLocation = False Then
App.Runtime.SetMainFormText(App.Info.Connections.DefaultConnectionsPath & "\" & App.Info.Connections.DefaultConnectionsFile)
Else
App.Runtime.SetMainFormText(My.Settings.CustomConsPath)
End If
SetMainFormText(GetStartupConnectionFileName())
App.Runtime.Startup.DestroySQLUpdateHandlerAndStopTimer()

View File

@@ -163,7 +163,7 @@
<value>Einstellungen jetzt anpassen</value>
</data>
<data name="strAskUpdatesCommandRecommended" xml:space="preserve">
<value>Verwende die empflohlenen Einstellungen</value>
<value>Verwende die empfohlenen Einstellungen</value>
</data>
<data name="strAskUpdatesContent" xml:space="preserve">
<value>{0} kann automatisch nach Updates suchen die neue Funktionen und Bug Fixes enthalten können. Es wird empfohlen, dass Sie {0} erlauben wöchentlich nach Updates zu suchen.</value>

View File

@@ -606,7 +606,7 @@ Descrição do erro: {1}</value>
<value>Erros</value>
</data>
<data name="strErrorStartupConnectionFileLoad" xml:space="preserve">
<value>O arquivo de inicialização de ligação não pôde ser carregado.{0}{0}(2){0}{3}{0}{0}A fim de evitar perda de dados, {1} vai sair agora.</value>
<value>O arquivo de inicialização de ligação não pôde ser carregado.{0}{0}{2}{0}{3}{0}{0}A fim de evitar perda de dados, {1} vai sair agora.</value>
</data>
<data name="strErrorVerifyDatabaseVersionFailed" xml:space="preserve">
<value>VerifyDatabaseVersion (Config.Connections.Save) falhou. {0}</value>

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.71.*")>
<Assembly: AssemblyVersion("1.72.*")>
<Assembly: NeutralResourcesLanguageAttribute("en")>

View File

@@ -1,4 +1,5 @@
Imports mRemoteNG.Tools.LocalizedAttributes
Imports mRemoteNG.My
Imports mRemoteNG.Tools.LocalizedAttributes
Namespace Root
Namespace PuttySessions
@@ -9,7 +10,21 @@ Namespace Root
MyBase.New(RootType.PuttySessions)
End Sub
Private _name As String = Language.strPuttySavedSessionsRootName
<LocalizedDefaultValue("strPuttySavedSessionsRootName")> _
Public Overrides Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
If _name = value Then Return
_name = value
If TreeNode IsNot Nothing Then
TreeNode.Text = value
End If
Settings.PuttySavedSessionsName = value
End Set
End Property
Private _panel As String = My.Language.strGeneral
<LocalizedCategory("strCategoryDisplay", 1), _
@@ -20,7 +35,9 @@ Namespace Root
Return _panel
End Get
Set(ByVal value As String)
If _panel = value Then Return
_panel = value
Settings.PuttySavedSessionsPanel = value
End Set
End Property
End Class

View File

@@ -5,113 +5,57 @@ Imports mRemoteNG.Tools.LocalizedAttributes
Namespace Root
<DefaultProperty("Name")> _
Public Class Info
Public Sub New(ByVal typ As RootType)
_Type = typ
#Region "Constructors"
Public Sub New(ByVal rootType As RootType)
Type = rootType
End Sub
#Region "Properties"
Private _Name As String = My.Language.strConnections
<LocalizedCategory("strCategoryDisplay", 1), _
Browsable(True), _
[ReadOnly](False), _
Bindable(False), _
DefaultValue(""), _
DesignOnly(False), _
LocalizedDisplayName("strPropertyNameName"), _
LocalizedDescription("strPropertyDescriptionName"), _
Attributes.Root()> _
Public Overridable Property Name() As String
Get
Return Me._Name
End Get
Set(ByVal value As String)
Me._Name = value
End Set
End Property
Private _Password As Boolean
<LocalizedCategory("strCategoryDisplay", 1), _
Browsable(True), _
[ReadOnly](False), _
Bindable(False), _
DefaultValue(""), _
DesignOnly(False), _
LocalizedDisplayName("strPasswordProtect"), _
Attributes.Root(), _
TypeConverter(GetType(mRemoteNG.Tools.Misc.YesNoTypeConverter))> _
Public Property Password() As Boolean
Get
Return _Password
End Get
Set(ByVal value As Boolean)
_Password = value
End Set
End Property
Private _PasswordString As String
<Category(""), _
Browsable(False), _
[ReadOnly](False), _
Bindable(False), _
DefaultValue(""), _
DesignOnly(False)> _
Public Property PasswordString() As String
Get
Return _PasswordString
End Get
Set(ByVal value As String)
_PasswordString = value
End Set
End Property
Private _Type As Root.Info.RootType = RootType.Connection
<Category(""), _
Browsable(False), _
[ReadOnly](False), _
Bindable(False), _
DefaultValue(""), _
DesignOnly(False)> _
Public Property Type() As Root.Info.RootType
Get
Return _Type
End Get
Set(ByVal value As Root.Info.RootType)
_Type = value
End Set
End Property
Private _TreeNode As TreeNode
<Category(""), _
Browsable(False), _
[ReadOnly](False), _
Bindable(False), _
DefaultValue(""), _
DesignOnly(False)> _
Public Property TreeNode() As TreeNode
Get
Return Me._TreeNode
End Get
Set(ByVal value As TreeNode)
Me._TreeNode = value
End Set
End Property
#End Region
#Region "Public Properties"
Private _name As String = My.Language.strConnections
<LocalizedCategory("strCategoryDisplay", 1), _
Browsable(True), _
LocalizedDefaultValue("strConnections"), _
LocalizedDisplayName("strPropertyNameName"), _
LocalizedDescription("strPropertyDescriptionName")> _
Public Overridable Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
Debug.Print("Root.Info.Name.Set({0})", value)
If _name = value Then Return
_name = value
If TreeNode IsNot Nothing Then
TreeNode.Name = value
TreeNode.Text = value
End If
End Set
End Property
<LocalizedCategory("strCategoryDisplay", 1), _
Browsable(True), _
LocalizedDisplayName("strPasswordProtect"), _
TypeConverter(GetType(Tools.Misc.YesNoTypeConverter))> _
Public Property Password() As Boolean
<Browsable(False)> _
Public Property PasswordString() As String
<Browsable(False)> _
Public Property Type() As RootType
<Browsable(False)> _
Public Property TreeNode() As TreeNode
#End Region
#Region "Public Enumerations"
Public Enum RootType
Connection
Credential
PuttySessions
End Enum
Public Class Attributes
Public Class Root
Inherits Attribute
End Class
End Class
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,70 @@
Imports mRemoteNG.Connection.Protocol
Namespace Tools
Public Class PuttyTypeDetector
Public Shared Function GetPuttyType() As PuttyType
Return GetPuttyType(PuttyBase.PuttyPath)
End Function
Public Shared Function GetPuttyType(ByVal filename As String) As PuttyType
If IsPuttyNg(filename) Then Return PuttyType.PuttyNg
If IsKitty(filename) Then Return PuttyType.Kitty
If IsXming(filename) Then Return PuttyType.Xming
' Check this last
If IsPutty(filename) Then Return PuttyType.Putty
Return PuttyType.Unknown
End Function
Private Shared Function IsPutty(ByVal filename As String) As Boolean
Dim result As Boolean
Try
result = FileVersionInfo.GetVersionInfo(filename).InternalName.Contains("PuTTY")
Catch
result = False
End Try
Return result
End Function
Private Shared Function IsPuttyNg(filename As String) As Boolean
Dim result As Boolean
Try
result = FileVersionInfo.GetVersionInfo(filename).InternalName.Contains("PuTTYNG")
Catch
result = False
End Try
Return result
End Function
Private Shared Function IsKitty(filename As String) As Boolean
Dim result As Boolean
Try
result = FileVersionInfo.GetVersionInfo(filename).InternalName.Contains("PuTTY") _
And FileVersionInfo.GetVersionInfo(filename).Comments.Contains("KiTTY")
Catch
result = False
End Try
Return result
End Function
Private Shared Function IsXming(filename As String) As Boolean
Dim result As Boolean
Try
result = FileVersionInfo.GetVersionInfo(filename).InternalName.Contains("PuTTY") _
And FileVersionInfo.GetVersionInfo(filename).ProductVersion.Contains("Xming")
Catch
result = False
End Try
Return result
End Function
Public Enum PuttyType
Unknown = 0
Putty
PuttyNg
Kitty
Xming
End Enum
End Class
End Namespace

View File

@@ -74,6 +74,23 @@ Namespace Tools
End Property
End Class
<AttributeUsage(AttributeTargets.All, AllowMultiple:=False, Inherited:=True)> _
Public Class LocalizedDefaultValueAttribute
Inherits DefaultValueAttribute
Public Sub New(ByVal name As String)
MyBase.New(My.Language.ResourceManager.GetString(name))
End Sub
' This allows localized attributes in a derived class to override a matching
' non-localized attribute inherited from its base class
Public Overrides ReadOnly Property TypeId() As Object
Get
Return GetType(DefaultValueAttribute)
End Get
End Property
End Class
#Region "Special localization - with String.Format"
<AttributeUsage(AttributeTargets.All, AllowMultiple:=False, Inherited:=True)> _

View File

@@ -305,9 +305,9 @@ Namespace Tree
Public Shared Sub CloneNode(ByVal oldTreeNode As TreeNode, Optional ByVal parentNode As TreeNode = Nothing)
Try
If GetNodeType(oldTreeNode) = Type.Connection Then
Dim oldConnectionInfo As Connection.Info = oldTreeNode.Tag
Dim oldConnectionInfo As Connection.Info = DirectCast(oldTreeNode.Tag, Connection.Info)
Dim newConnectionInfo As Connection.Info = oldConnectionInfo.Copy
Dim newConnectionInfo As Connection.Info = oldConnectionInfo.Copy()
Dim newInheritance As Connection.Info.Inheritance = oldConnectionInfo.Inherit.Copy()
newInheritance.Parent = newConnectionInfo
newConnectionInfo.Inherit = newInheritance
@@ -332,8 +332,10 @@ Namespace Tree
parentNode.Nodes.Add(newTreeNode)
End If
ElseIf GetNodeType(oldTreeNode) = Type.Container Then
Dim newContainerInfo As Container.Info = TryCast(oldTreeNode.Tag, Container.Info).Copy
Dim newConnectionInfo As Connection.Info = TryCast(oldTreeNode.Tag, Container.Info).ConnectionInfo.Copy
Dim oldContainerInfo As Container.Info = DirectCast(oldTreeNode.Tag, Container.Info)
Dim newContainerInfo As Container.Info = oldContainerInfo.Copy()
Dim newConnectionInfo As Connection.Info = oldContainerInfo.ConnectionInfo.Copy()
newContainerInfo.ConnectionInfo = newConnectionInfo
Dim newTreeNode As New TreeNode(newContainerInfo.Name)

View File

@@ -1,5 +1,7 @@
Imports mRemoteNG.Messages
Imports mRemoteNG.My
Imports mRemoteNG.Connection.Protocol
Imports mRemoteNG.Root
Imports WeifenLuo.WinFormsUI.Docking
Imports System.Net.NetworkInformation
Imports mRemoteNG.App.Runtime
@@ -21,10 +23,16 @@ Namespace UI
Private components As System.ComponentModel.IContainer
Friend WithEvents propertyGridContextMenu As System.Windows.Forms.ContextMenuStrip
Friend WithEvents propertyGridContextMenuShowHelpText As System.Windows.Forms.ToolStripMenuItem
Friend WithEvents propertyGridContextMenuReset As System.Windows.Forms.ToolStripMenuItem
Friend WithEvents ToolStripSeparator1 As System.Windows.Forms.ToolStripSeparator
Friend WithEvents pGrid As Azuria.Common.Controls.FilteredPropertyGrid
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.pGrid = New Azuria.Common.Controls.FilteredPropertyGrid()
Me.propertyGridContextMenu = New System.Windows.Forms.ContextMenuStrip(Me.components)
Me.propertyGridContextMenuReset = New System.Windows.Forms.ToolStripMenuItem()
Me.ToolStripSeparator1 = New System.Windows.Forms.ToolStripSeparator()
Me.propertyGridContextMenuShowHelpText = New System.Windows.Forms.ToolStripMenuItem()
Me.btnShowInheritance = New System.Windows.Forms.ToolStripButton()
Me.btnShowDefaultInheritance = New System.Windows.Forms.ToolStripButton()
Me.btnShowProperties = New System.Windows.Forms.ToolStripButton()
@@ -32,8 +40,6 @@ Namespace UI
Me.btnIcon = New System.Windows.Forms.ToolStripButton()
Me.btnHostStatus = New System.Windows.Forms.ToolStripButton()
Me.cMenIcons = New System.Windows.Forms.ContextMenuStrip(Me.components)
Me.propertyGridContextMenu = New System.Windows.Forms.ContextMenuStrip(Me.components)
Me.propertyGridContextMenuShowHelpText = New System.Windows.Forms.ToolStripMenuItem()
Me.propertyGridContextMenu.SuspendLayout()
Me.SuspendLayout()
'
@@ -54,6 +60,29 @@ Namespace UI
Me.pGrid.TabIndex = 0
Me.pGrid.UseCompatibleTextRendering = True
'
'propertyGridContextMenu
'
Me.propertyGridContextMenu.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.propertyGridContextMenuReset, Me.ToolStripSeparator1, Me.propertyGridContextMenuShowHelpText})
Me.propertyGridContextMenu.Name = "propertyGridContextMenu"
Me.propertyGridContextMenu.Size = New System.Drawing.Size(157, 76)
'
'propertyGridContextMenuReset
'
Me.propertyGridContextMenuReset.Name = "propertyGridContextMenuReset"
Me.propertyGridContextMenuReset.Size = New System.Drawing.Size(156, 22)
Me.propertyGridContextMenuReset.Text = "&Reset"
'
'ToolStripSeparator1
'
Me.ToolStripSeparator1.Name = "ToolStripSeparator1"
Me.ToolStripSeparator1.Size = New System.Drawing.Size(153, 6)
'
'propertyGridContextMenuShowHelpText
'
Me.propertyGridContextMenuShowHelpText.Name = "propertyGridContextMenuShowHelpText"
Me.propertyGridContextMenuShowHelpText.Size = New System.Drawing.Size(156, 22)
Me.propertyGridContextMenuShowHelpText.Text = "&Show Help Text"
'
'btnShowInheritance
'
Me.btnShowInheritance.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
@@ -117,18 +146,6 @@ Namespace UI
Me.cMenIcons.Name = "cMenIcons"
Me.cMenIcons.Size = New System.Drawing.Size(61, 4)
'
'propertyGridContextMenu
'
Me.propertyGridContextMenu.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.propertyGridContextMenuShowHelpText})
Me.propertyGridContextMenu.Name = "propertyGridContextMenu"
Me.propertyGridContextMenu.Size = New System.Drawing.Size(157, 26)
'
'propertyGridContextMenuShowHelpText
'
Me.propertyGridContextMenuShowHelpText.Name = "ContextMenuShowHelpText"
Me.propertyGridContextMenuShowHelpText.Size = New System.Drawing.Size(156, 22)
Me.propertyGridContextMenuShowHelpText.Text = "&Show Help Text"
'
'Config
'
Me.ClientSize = New System.Drawing.Size(226, 530)
@@ -629,31 +646,21 @@ Namespace UI
End If
End If
If TypeOf pGrid.SelectedObject Is Root.PuttySessions.Info Then
Dim puttyRootInfo As Root.PuttySessions.Info = pGrid.SelectedObject
Dim rootInfo As Info = TryCast(pGrid.SelectedObject, Info)
If (rootInfo IsNot Nothing) Then
Select Case e.ChangedItem.PropertyDescriptor.Name
Case "Name"
puttyRootInfo.TreeNode.Text = puttyRootInfo.Name
Settings.PuttySavedSessionsName = puttyRootInfo.Name
Case "Panel"
Settings.PuttySavedSessionsPanel = puttyRootInfo.Panel
End Select
ElseIf TypeOf Me.pGrid.SelectedObject Is mRemoteNG.Root.Info Then
Dim rInfo As mRemoteNG.Root.Info = Me.pGrid.SelectedObject
Case "Password"
If rootInfo.Password = True Then
Dim password As String = Tools.Misc.PasswordDialog
Select Case e.ChangedItem.Label
Case My.Language.strPasswordProtect
If rInfo.Password = True Then
Dim pw As String = Tools.Misc.PasswordDialog
If pw <> "" Then
rInfo.PasswordString = pw
If String.IsNullOrEmpty(password) Then
rootInfo.Password = False
Else
rInfo.Password = False
rootInfo.PasswordString = password
End If
End If
Case My.Language.strPropertyNameName
App.Runtime.Windows.treeForm.tvConnections.SelectedNode.Text = Me.pGrid.SelectedObject.Name
Case "Name"
'Windows.treeForm.tvConnections.SelectedNode.Text = pGrid.SelectedObject.Name
End Select
End If
@@ -1514,14 +1521,37 @@ Namespace UI
#End Region
Private Sub propertyGridContextMenu_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles propertyGridContextMenu.Opening
propertyGridContextMenuShowHelpText.Checked = Settings.ShowConfigHelpText
Try
propertyGridContextMenuShowHelpText.Checked = Settings.ShowConfigHelpText
Dim gridItem As GridItem = pGrid.SelectedGridItem
propertyGridContextMenuReset.Enabled = (pGrid.SelectedObject IsNot Nothing AndAlso _
gridItem IsNot Nothing AndAlso _
gridItem.PropertyDescriptor IsNot Nothing AndAlso _
gridItem.PropertyDescriptor.CanResetValue(pGrid.SelectedObject))
Catch ex As Exception
MessageCollector.AddExceptionMessage("UI.Window.Config.propertyGridContextMenu_Opening() failed.", ex, MessageClass.ErrorMsg, True)
End Try
End Sub
Private Sub propertyGridContextMenu_Click(sender As Object, e As EventArgs) Handles propertyGridContextMenuShowHelpText.Click
Private Sub propertyGridContextMenuReset_Click(sender As System.Object, e As EventArgs) Handles propertyGridContextMenuReset.Click
Try
Dim gridItem As GridItem = pGrid.SelectedGridItem
If pGrid.SelectedObject IsNot Nothing AndAlso _
gridItem IsNot Nothing AndAlso _
gridItem.PropertyDescriptor IsNot Nothing AndAlso _
gridItem.PropertyDescriptor.CanResetValue(pGrid.SelectedObject) Then
pGrid.ResetSelectedProperty()
End If
Catch ex As Exception
MessageCollector.AddExceptionMessage("UI.Window.Config.propertyGridContextMenuReset_Click() failed.", ex, MessageClass.ErrorMsg, True)
End Try
End Sub
Private Sub propertyGridContextMenuShowHelpText_Click(sender As Object, e As EventArgs) Handles propertyGridContextMenuShowHelpText.Click
propertyGridContextMenuShowHelpText.Checked = Not propertyGridContextMenuShowHelpText.Checked
End Sub
Private Sub propertyGridContextMenu_CheckedChanged(sender As Object, e As EventArgs) Handles propertyGridContextMenuShowHelpText.CheckedChanged
Private Sub propertyGridContextMenuShowHelpText_CheckedChanged(sender As Object, e As EventArgs) Handles propertyGridContextMenuShowHelpText.CheckedChanged
Settings.ShowConfigHelpText = propertyGridContextMenuShowHelpText.Checked
pGrid.HelpVisible = propertyGridContextMenuShowHelpText.Checked
End Sub

View File

@@ -129,10 +129,10 @@ Namespace UI
With data
impersonator.StartImpersonation(.Domain, .Username, .Password)
If Not terminalSessions.OpenConnection(.Hostname) Then Return
serverHandle = terminalSessions.ServerHandle
serverHandle = terminalSessions.OpenConnection(.Hostname)
If serverHandle = 0 Then Return
GetSessions(terminalSessions)
GetSessions(terminalSessions, serverHandle)
End With
_retrieved = True
@@ -149,11 +149,11 @@ Namespace UI
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
Private Sub GetSessions(ByVal terminalSessions As mRemoteNG.Connection.Protocol.RDP.TerminalSessions, ByVal serverHandle As Long)
Dim rdpSessions As mRemoteNG.Connection.Protocol.RDP.SessionsCollection = terminalSessions.GetSessions(serverHandle)
For Each session As mRemoteNG.Connection.Protocol.RDP.Session In rdpSessions
Dim item As New ListViewItem
item.Tag = session.SessionID
item.Tag = session.SessionId
item.Text = session.SessionUser
item.SubItems.Add(session.SessionState)
item.SubItems.Add(Replace(session.SessionName, vbNewLine, ""))
@@ -174,13 +174,13 @@ Namespace UI
impersonator.StartImpersonation(.Domain, .Username, .Password)
If terminalSessions.OpenConnection(.Hostname) Then
serverHandle = terminalSessions.ServerHandle
terminalSessions.KillSession(.SessionId)
serverHandle = terminalSessions.OpenConnection(.Hostname)
If Not serverHandle = 0 Then
terminalSessions.KillSession(serverHandle, .SessionId)
End If
ClearList()
GetSessions(terminalSessions)
GetSessions(terminalSessions, serverHandle)
_retrieved = True
End With

View File

@@ -766,7 +766,7 @@ Namespace UI
cMenTreeToolsSort.Enabled = False
cMenTreeToolsExternalApps.Enabled = False
cMenTreeDuplicate.Enabled = False
cMenTreeRename.Enabled = False
cMenTreeRename.Enabled = True
cMenTreeDelete.Enabled = False
cMenTreeMoveUp.Enabled = False
cMenTreeMoveDown.Enabled = False
@@ -1088,6 +1088,7 @@ Namespace UI
End If
newContainerInfo.ConnectionInfo = New mRemoteNG.Connection.Info(newContainerInfo)
newContainerInfo.ConnectionInfo.Name = newNode.Text
' We can only inherit from a container node, not the root node or connection nodes
If mRemoteNG.Tree.Node.GetNodeType(parentNode) = mRemoteNG.Tree.Node.Type.Container Then

View File

@@ -186,7 +186,10 @@
<Compile Include="Config\Config.Settings.Providers.vb" />
<Compile Include="Config\Config.Settings.Save.vb" />
<Compile Include="Config\ConfirmClose.vb" />
<Compile Include="Config\PuttySessions.vb" />
<Compile Include="Config\Putty\RegistryProvider.vb" />
<Compile Include="Config\Putty\XmingProvider.vb" />
<Compile Include="Config\Putty\Sessions.vb" />
<Compile Include="Config\Putty\Provider.vb" />
<Compile Include="Controls\QuickConnectComboBox.vb">
<SubType>Component</SubType>
</Compile>
@@ -280,6 +283,7 @@
<Compile Include="Security\Security.Save.vb" />
<Compile Include="Tools\IeBrowserEmulation.vb" />
<Compile Include="Tools\ProcessController.vb" />
<Compile Include="Tools\PuttyTypeDetector.vb" />
<Compile Include="Tools\PuttyProcessController.vb" />
<Compile Include="Tools\ReconnectGroup.Designer.vb">
<DependentUpon>ReconnectGroup.vb</DependentUpon>