private void renameToolStripMenuItem_Click(object sender, EventArgs e) { TreeNode node = this.treeView1.SelectedNode; if (node != null) { dlgRenameItem dialog = new dlgRenameItem(); dialog.Text = "Rename Folder"; dialog.ItemName = node.Text; dialog.DetailName = ""; dialog.ItemNameValidator = delegate(string txt, out string error) { error = String.Empty; if (node.Parent.Nodes.ContainsKey(txt) && txt != node.Text) { error = "Node with same name exists"; } else if (txt.Contains(SessionIdDelim)) { error = "Invalid character ( " + SessionIdDelim + " ) in name"; } return(string.IsNullOrEmpty(error)); }; if (dialog.ShowDialog(this) == DialogResult.OK && node.Text != dialog.ItemName) { node.Text = dialog.ItemName; node.Name = dialog.ItemName; UpdateSessionId(node); SuperPuTTY.SaveSessions(); ResortNodes(); } } }
private void removeFolderToolStripMenuItem_Click(object sender, EventArgs e) { TreeNode node = this.treeView1.SelectedNode; if (node != null) { if (node.Nodes.Count > 0) { List <SessionData> sessions = new List <SessionData>(); GetAllSessions(node, sessions); if (DialogResult.Yes == MessageBox.Show( "Remove Folder [" + node.Text + "] and [" + sessions.Count + "] sessions?", "Remove Folder?", MessageBoxButtons.YesNo)) { foreach (SessionData session in sessions) { SuperPuTTY.RemoveSession(session.SessionId); } node.Remove(); SuperPuTTY.ReportStatus("Removed Folder, {0} and {1} sessions", node.Text, sessions.Count); SuperPuTTY.SaveSessions(); } } else { node.Remove(); SuperPuTTY.ReportStatus("Removed Folder, {0}", node.Text); } } }
/// <summary> /// Delete a session entry from the treeview and the registry /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void deleteToolStripMenuItem_Click(object sender, EventArgs e) { SessionData session = (SessionData)treeView1.SelectedNode.Tag; if (MessageBox.Show("Are you sure you want to delete " + session.SessionName + "?", "Delete Session?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { //session.RegistryRemove(session.SessionName); treeView1.SelectedNode.Remove(); SuperPuTTY.RemoveSession(session.SessionId); SuperPuTTY.SaveSessions(); //m_SessionsById.Remove(session.SessionId); } }
private void sessionDetailPropertyGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { SessionData Session = sessionDetailPropertyGrid.SelectedObject as SessionData; if (Session != null) { String HostPropertyName = "Host"; String PuttySessionPropertyName = "PuttySession"; if (e.ChangedItem.PropertyDescriptor.Name == HostPropertyName || e.ChangedItem.PropertyDescriptor.Name == PuttySessionPropertyName) { if (String.IsNullOrEmpty(Session.PuttySession) && String.IsNullOrEmpty(Session.Host)) { if (e.ChangedItem.PropertyDescriptor.Name == HostPropertyName) { MessageBox.Show("A host name must be specified if a Putty Session Profile is not selected"); Session.Host = (String)e.OldValue; } else { MessageBox.Show("A Putty Session Profile must be selected if a Host Name is not provided"); Session.PuttySession = (String)e.OldValue; } sessionDetailPropertyGrid.Refresh(); } } String ExtraArgsPropertyName = "ExtraArgs"; if (e.ChangedItem.PropertyDescriptor.Name == ExtraArgsPropertyName) { if (!String.IsNullOrEmpty(CommandLineOptions.getcommand(Session.ExtraArgs, "-pw"))) { if (MessageBox.Show("SuperPutty save the password in Sessions.xml file in plain text.\nUse a password in 'Extra PuTTY Arguments' is very insecure.\nFor a secure connection use SSH authentication with Pageant. \nSelect yes, if you want save the password", "Are you sure that you want to save the password?", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1) == DialogResult.Cancel) { Session.ExtraArgs = (String)e.OldValue; return; } } sessionDetailPropertyGrid.Refresh(); } Session.SessionId = SessionData.CombineSessionIds(SessionData.GetSessionParentId(Session.SessionId), Session.SessionName); } SuperPuTTY.SaveSessions(); }
/// <summary> /// Create/Update a session entry /// </summary> /// <param name="sender">The toolstripmenuitem control that was clicked</param> /// <param name="e">An Empty EventArgs object</param> private void CreateOrEditSessionToolStripMenuItem_Click(object sender, EventArgs e) { SessionData session = null; TreeNode node = null; TreeNode nodeRef = this.nodeRoot; string title = null; if (sender is ToolStripMenuItem) { ToolStripMenuItem menuItem = (ToolStripMenuItem)sender; bool isFolderNode = IsFolderNode(treeView1.SelectedNode); if (menuItem.Text.ToLower().Equals("new") || isFolderNode) { session = new SessionData(); nodeRef = isFolderNode ? treeView1.SelectedNode : treeView1.SelectedNode.Parent; title = "Create New Session"; } else if (menuItem == this.createLikeToolStripMenuItem) { // copy as session = (SessionData)((SessionData)treeView1.SelectedNode.Tag).Clone(); session.SessionId = SuperPuTTY.MakeUniqueSessionId(session.SessionId); session.SessionName = SessionData.GetSessionNameFromId(session.SessionId); nodeRef = treeView1.SelectedNode.Parent; title = "Create New Session Like " + session.OldName; } else { // edit, session node selected // We make a clone of the session since we do not want to directly edit the real object. session = (SessionData)((SessionData)treeView1.SelectedNode.Tag).Clone(); node = treeView1.SelectedNode; nodeRef = node.Parent; title = "Edit Session: " + session.SessionName; } } dlgEditSession form = new dlgEditSession(session, this.treeView1.ImageList) { Text = title }; form.SessionNameValidator += delegate(string txt, out string error) { bool IsValid = ValidateSessionNameChange(nodeRef, node, txt, out error); return(IsValid); }; if (form.ShowDialog(this) == DialogResult.OK) { /* "node" will only be assigned if we're editing an existing session entry */ if (node == null) { // get the path up to the ref (parent) node if (nodeRoot != nodeRef) { UpdateSessionId(nodeRef, session); session.SessionId = SessionData.CombineSessionIds(session.SessionId, session.SessionName); } SuperPuTTY.AddSession(session); // find new node and select it TreeNode nodeNew = nodeRef.Nodes[session.SessionName]; if (nodeNew != null) { this.treeView1.SelectedNode = nodeNew; } } else { SessionData RealSession = (SessionData)treeView1.SelectedNode.Tag; RealSession.CopyFrom(session); RealSession.SessionName = session.SessionName; this.treeView1.SelectedNode = node; } //treeView1.ExpandAll(); SuperPuTTY.SaveSessions(); } }
public void BeginGetDirectoryListing(string path, DirListingCallback callback) { if (m_Session == null) { callback(RequestResult.SessionInvalid, null); return; } List <FileEntry> files = new List <FileEntry>(); Stopwatch timeoutWatch = new Stopwatch(); /* * Check that we have a username either stored from previous sessions, or loaded * from the registry. If PPK Authentication is being used that will override * any values entered in the login dialog */ if (String.IsNullOrEmpty(m_Session.Username)) { if (m_Login.ShowDialog(SuperPuTTY.MainForm) == System.Windows.Forms.DialogResult.OK) { m_Session.Username = m_Login.Username; m_Session.Password = m_Login.Password; if (m_Login.Remember) { //Session.SaveToRegistry(); // passwords are *never* saved and stored permanently SuperPuTTY.SaveSessions(); } } else { Logger.Log("Cancel connection"); callback(RequestResult.CancelLogin, null); } } Thread threadListFiles = new Thread(delegate() { m_processDir = new Process(); m_processDir.EnableRaisingEvents = true; m_processDir.StartInfo.UseShellExecute = false; m_processDir.StartInfo.RedirectStandardError = true; //m_processDir.StartInfo.RedirectStandardInput = true; m_processDir.StartInfo.RedirectStandardOutput = true; m_processDir.StartInfo.CreateNoWindow = true; m_processDir.StartInfo.FileName = SuperPuTTY.Settings.PscpExe; // process the various options from the session object and convert them into arguments pscp can understand string args = MakeArgs(m_Session, true, path); Logger.Log("Sending Command: '{0} {1}'", m_processDir.StartInfo.FileName, MakeArgs(m_Session, false, path)); m_processDir.StartInfo.Arguments = args; /* * Handle output from spawned pscp.exe process, handle any data received and parse * any lines that look like a directory listing. */ m_processDir.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrEmpty(e.Data)) { if (e.Data.Equals(PUTTY_ARGUMENTS_HELP_HEADER)) { m_processDir.CancelOutputRead(); m_processDir.Kill(); return; } else if (e.Data.StartsWith("Listing directory ")) { // This just tells us the current directory, however since we're the ones that requested it // we already have this information. But this traps it so its not sent through the directory // entry parser. } else if (e.Data.Equals(PUTTY_INTERACTIVE_AUTH) || e.Data.Contains("password: "******"Username/Password invalid or not sent"); callback(RequestResult.RetryAuthentication, null); } else { timeoutWatch.Reset(); lock (files) { FileEntry file; if (TryParseFileLine(e.Data, out file)) { files.Add(file); } if (files.Count > 0) { callback(RequestResult.ListingFollows, files); } } } } }; m_processDir.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrEmpty(e.Data)) { if (e.Data.Contains(PUTTY_NO_KEY)) { m_processDir.CancelErrorRead(); m_processDir.Kill(); System.Windows.Forms.MessageBox.Show("The key of the host you are attempting to connect to has changed or is not cached \n" + "You must connect to this host with with a PuTTY ssh terminal to accept the key and store it in the cache", "Host Key not found or changed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Stop); } else { Logger.Log("Error Data:\n\t'{0}'", e.Data.TrimEnd()); // 'ssh_init: Host does not exist' } } }; m_processDir.Exited += delegate(object sender, EventArgs e) { if (m_processDir.ExitCode != 0) { Logger.Log("Process Exited (Failure): {0}", m_processDir.ExitCode); callback(RequestResult.UnknownError, null); if (m_PuttyClosed != null) { m_PuttyClosed(true); } } else { Logger.Log("Process Exited: {0}", m_processDir.ExitCode); if (m_PuttyClosed != null) { m_PuttyClosed(false); } } m_DirIsBusy = false; }; try { m_processDir.Start(); } catch (Win32Exception e) { if (e.NativeErrorCode == 2) // File Not Found { Logger.Log(e); } else if (e.NativeErrorCode == 4) // Acess Denied { Logger.Log(e); } } m_processDir.BeginErrorReadLine(); m_processDir.BeginOutputReadLine(); m_processDir.WaitForExit(); }); /* Only allow one directory list request at a time */ if (!m_DirIsBusy) { m_DirIsBusy = true; threadListFiles.Name = "List Remote Directory"; threadListFiles.IsBackground = true; threadListFiles.Start(); } else { return; } Thread timeoutThread = new Thread(delegate() { while (m_DirIsBusy) { /* * if no data received in 5 seconds we'll stop the process, * This allows us to capture any interactive prompts/messages * sent to us by putty. */ if (timeoutWatch.Elapsed.Seconds >= 5) { Logger.Log("Timeout after {0} seconds", timeoutWatch.Elapsed.Seconds); if (!m_processDir.HasExited) { m_processDir.Kill(); } m_processDir.CancelErrorRead(); m_processDir.CancelOutputRead(); return; } Thread.Sleep(1000); } }); timeoutThread.Name = "Timeout Watcher"; timeoutThread.IsBackground = true; timeoutThread.Start(); timeoutWatch.Start(); }
/// <summary>Open a new putty window with its settings being passed in a <seealso cref="SessionData"/> object</summary> /// <param name="session">The <seealso cref="SessionData"/> object containing the settings</param> public static ctlPuttyPanel OpenProtoSession(SessionData session) { Log.InfoFormat("Opening putty session, id={0}", session == null ? "" : session.SessionId); ctlPuttyPanel panel = null; if (session != null) { String Executable = PuttyStartInfo.GetExecutable(session); if (String.IsNullOrEmpty(Executable)) { MessageBox.Show("Error trying to create session: " + session.ToString() + "\nExecutable not set for " + session.Proto.ToString() + " protocol." + "\nGo to tools->options->General tab to set the path to the executable." , "Failed to create a session", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } if (!File.Exists(Executable)) { MessageBox.Show("Error trying to create session: " + session.ToString() + "\nExecutable not found for " + session.Proto.ToString() + " protocol." + "\nThe path for the executable was set as \"" + Executable + "\"." + "\nGo to tools->options->General tab to set the path to the executable." , "Failed to create a session", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } // This is the callback fired when the panel containing the terminal is closed // We use this to save the last docking location and to close the panel PuttyClosedCallback callback = delegate { if (panel != null) { // save the last dockstate (if it has been changed) if (session.LastDockstate != panel.DockState && panel.DockState != DockState.Unknown && panel.DockState != DockState.Hidden) { session.LastDockstate = panel.DockState; SuperPuTTY.SaveSessions(); } if (panel.InvokeRequired) { panel.BeginInvoke((MethodInvoker) delegate { panel.Close(); }); } else { panel.Close(); } } }; try { panel = new ctlPuttyPanel(session, callback); ApplyDockRestrictions(panel); ApplyIconForWindow(panel, session); panel.Show(MainForm.DockPanel, session.LastDockstate); ReportStatus("Opened session: {0} [{1}]", session.SessionId, session.Proto); if (!String.IsNullOrEmpty(session.SPSLFileName) && File.Exists(session.SPSLFileName)) { ExecuteScriptEventArgs scriptArgs = new ExecuteScriptEventArgs() { Script = File.ReadAllText(session.SPSLFileName), Handle = panel.AppPanel.AppWindowHandle }; if (!String.IsNullOrEmpty(scriptArgs.Script)) { SPSL.BeginExecuteScript(scriptArgs); } } } catch (InvalidOperationException ex) { MessageBox.Show("Error trying to create session " + ex.Message, "Failed to create session panel", MessageBoxButtons.OK, MessageBoxIcon.Error); } } return(panel); }
/// <summary>Open a new putty window with its settings being passed in a <seealso cref="SessionData"/> object</summary> /// <param name="session">The <seealso cref="SessionData"/> object containing the settings</param> public static ctlPuttyPanel OpenProtoSession(SessionData session) { Log.InfoFormat("Opening putty session, id={0}", session == null ? "" : session.SessionId); ctlPuttyPanel panel = null; if (session != null) { String Executable = PuttyStartInfo.GetExecutable(session); if (String.IsNullOrEmpty(Executable)) { MessageBox.Show("Error trying to create session: " + session.ToString() + "\nExecutable not set for " + session.Proto.ToString() + " protocol." + "\nGo to tools->options->General tab to set the path to the executable." , "Failed to create a session", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } if (!File.Exists(Executable)) { MessageBox.Show("Error trying to create session: " + session.ToString() + "\nExecutable not found for " + session.Proto.ToString() + " protocol." + "\nThe path for the executable was set as \"" + Executable + "\"." + "\nGo to tools->options->General tab to set the path to the executable." , "Failed to create a session", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } // This is the callback fired when the panel containing the terminal is closed // We use this to save the last docking location and to close the panel PuttyClosedCallback callback = delegate { if (panel != null) { // save the last dockstate (if it has been changed) if (session.LastDockstate != panel.DockState && panel.DockState != DockState.Unknown && panel.DockState != DockState.Hidden) { session.LastDockstate = panel.DockState; SuperPuTTY.SaveSessions(); } if (panel.InvokeRequired) { panel.BeginInvoke((MethodInvoker) delegate { panel.Close(); }); } else { panel.Close(); } } }; try { panel = new ctlPuttyPanel(session, callback); ApplyDockRestrictions(panel); ApplyIconForWindow(panel, session); panel.Show(MainForm.DockPanel, session.LastDockstate); ReportStatus("Opened session: {0} [{1}]", session.SessionId, session.Proto); if (!String.IsNullOrWhiteSpace(session.SPSLFileName)) { String fileName = session.SPSLFileName; String script = String.Empty; if (Regex.IsMatch(fileName, @"^https?:\/\/", RegexOptions.IgnoreCase)) { try { HttpWebRequest req = WebRequest.CreateHttp(fileName); var response = req.GetResponse(); using (var stream = new StreamReader(response.GetResponseStream())) { script = stream.ReadToEnd(); } } catch (Exception) { script = String.Empty; } } else { if (fileName.StartsWith("file://", StringComparison.OrdinalIgnoreCase)) { fileName = fileName.Substring("file://".Length); } if (File.Exists(fileName)) { script = File.ReadAllText(fileName); } } if (!String.IsNullOrEmpty(script)) { ExecuteScriptEventArgs scriptArgs = new ExecuteScriptEventArgs() { Script = script, Handle = panel.AppPanel.AppWindowHandle }; SPSL.BeginExecuteScript(scriptArgs); } } } catch (InvalidOperationException ex) { MessageBox.Show("Error trying to create session " + ex.Message, "Failed to create session panel", MessageBoxButtons.OK, MessageBoxIcon.Error); } } return(panel); }