diff --git a/mRemoteV1/App/NativeMethods.cs b/mRemoteV1/App/NativeMethods.cs index 44aa0b96..c9250671 100644 --- a/mRemoteV1/App/NativeMethods.cs +++ b/mRemoteV1/App/NativeMethods.cs @@ -44,6 +44,9 @@ namespace mRemoteNG.App [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + internal static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam); @@ -378,6 +381,11 @@ namespace mRemoteNG.App /// public const int WM_KEYUP = 0x101; + /// + /// + /// + public const int WM_CHAR = 0x102; + /// /// /// diff --git a/mRemoteV1/App/Windows.cs b/mRemoteV1/App/Windows.cs index e2020774..faecf0ed 100644 --- a/mRemoteV1/App/Windows.cs +++ b/mRemoteV1/App/Windows.cs @@ -18,6 +18,8 @@ namespace mRemoteNG.App private static DockContent _helpPanel = new DockContent(); private static ExternalToolsWindow _externalappsForm; private static DockContent _externalappsPanel = new DockContent(); + private static SSHCommandWIndow _sshcommandForm; + private static DockContent _sshcommandPanel = new DockContent(); private static PortScanWindow _portscanForm; private static DockContent _portscanPanel = new DockContent(); private static UltraVNCWindow _ultravncscForm; @@ -33,6 +35,8 @@ namespace mRemoteNG.App public static DockContent ErrorsPanel { get; set; } = new DockContent(); public static ScreenshotManagerWindow ScreenshotForm { get; set; } public static DockContent ScreenshotPanel { get; set; } = new DockContent(); + public static SSHCommandWIndow SSHCommandForm { get; set; } + public static DockContent SSHCommandPanel { get; set; } = new DockContent(); public static UpdateWindow UpdateForm { get; set; } public static DockContent UpdatePanel { get; set; } = new DockContent(); public static SSHTransferWindow SshtransferForm { get; set; } @@ -100,6 +104,15 @@ namespace mRemoteNG.App } _externalappsForm.Show(frmMain.Default.pnlDock); } + else if (windowType.Equals(WindowType.SSHCommandWindow)) + { + if (_sshcommandForm == null || _sshcommandForm.IsDisposed) + { + _sshcommandForm = new SSHCommandWIndow(_sshcommandPanel); + _sshcommandPanel = _sshcommandForm; + } + _externalappsForm.Show(frmMain.Default.pnlDock); + } else if (windowType.Equals(WindowType.PortScan)) { _portscanForm = new PortScanWindow(_portscanPanel); diff --git a/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs b/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs index 1728e8b9..b7ecbf5c 100644 --- a/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs +++ b/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs @@ -76,6 +76,9 @@ namespace mRemoteNG.Config.Settings if (persistString == typeof(ScreenshotManagerWindow).ToString()) return Windows.ScreenshotPanel; + + if (persistString == typeof(SSHCommandWIndow).ToString()) + return Windows.SSHCommandPanel; } catch (Exception ex) { @@ -99,6 +102,9 @@ namespace mRemoteNG.Config.Settings Windows.ScreenshotForm = new ScreenshotManagerWindow(Windows.ScreenshotPanel); Windows.ScreenshotPanel = Windows.ScreenshotForm; + Windows.SSHCommandForm = new SSHCommandWIndow(Windows.SSHCommandPanel); + Windows.SSHCommandPanel = Windows.SSHCommandForm; + Windows.UpdateForm = new UpdateWindow(Windows.UpdatePanel); Windows.UpdatePanel = Windows.UpdateForm; } diff --git a/mRemoteV1/Connection/Protocol/PuttyBase.cs b/mRemoteV1/Connection/Protocol/PuttyBase.cs index bb5afa51..73f4e0d2 100644 --- a/mRemoteV1/Connection/Protocol/PuttyBase.cs +++ b/mRemoteV1/Connection/Protocol/PuttyBase.cs @@ -22,7 +22,7 @@ namespace mRemoteNG.Connection.Protocol protected Putty_SSHVersion PuttySSHVersion { private get; set; } - private IntPtr PuttyHandle { get; set; } + public IntPtr PuttyHandle { get; set; } private Process PuttyProcess { get; set; } diff --git a/mRemoteV1/UI/Forms/frmMain.Designer.cs b/mRemoteV1/UI/Forms/frmMain.Designer.cs index 4f19b58d..08c8a14b 100644 --- a/mRemoteV1/UI/Forms/frmMain.Designer.cs +++ b/mRemoteV1/UI/Forms/frmMain.Designer.cs @@ -61,6 +61,7 @@ namespace mRemoteNG.UI.Forms this.mMenViewConfig = new System.Windows.Forms.ToolStripMenuItem(); this.mMenViewErrorsAndInfos = new System.Windows.Forms.ToolStripMenuItem(); this.mMenViewScreenshotManager = new System.Windows.Forms.ToolStripMenuItem(); + this.mMenViewMultiPuttyCommand = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.mMenViewJumpTo = new System.Windows.Forms.ToolStripMenuItem(); this.mMenViewJumpToConnectionsConfig = new System.Windows.Forms.ToolStripMenuItem(); @@ -336,6 +337,7 @@ namespace mRemoteNG.UI.Forms this.mMenViewConfig, this.mMenViewErrorsAndInfos, this.mMenViewScreenshotManager, + this.mMenViewMultiPuttyCommand, this.ToolStripSeparator1, this.mMenViewJumpTo, this.mMenViewResetLayout, @@ -406,6 +408,13 @@ namespace mRemoteNG.UI.Forms this.mMenViewScreenshotManager.Size = new System.Drawing.Size(228, 22); this.mMenViewScreenshotManager.Text = "Screenshot Manager"; this.mMenViewScreenshotManager.Click += new System.EventHandler(this.mMenViewScreenshotManager_Click); + // + // mMenViewMultiPuttyCommand + // + this.mMenViewMultiPuttyCommand.Name = "mMenViewMultiPuttyCommand"; + this.mMenViewMultiPuttyCommand.Size = new System.Drawing.Size(228, 22); + this.mMenViewMultiPuttyCommand.Text = "Multi Putty Commander"; + this.mMenViewMultiPuttyCommand.Click += new System.EventHandler(this.mMenViewMultiPuttyCommand_Click); // // ToolStripSeparator1 // @@ -842,6 +851,7 @@ namespace mRemoteNG.UI.Forms internal System.Windows.Forms.ToolStripMenuItem mMenInfoDonate; internal System.Windows.Forms.ToolStripSeparator mMenViewSep3; internal ToolStripSplitButton btnQuickConnect; + internal System.Windows.Forms.ToolStripMenuItem mMenViewMultiPuttyCommand; internal System.Windows.Forms.ToolStripMenuItem mMenViewJumpTo; internal System.Windows.Forms.ToolStripMenuItem mMenViewJumpToConnectionsConfig; internal System.Windows.Forms.ToolStripMenuItem mMenViewJumpToErrorsInfos; diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index d76d507b..316df31c 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -705,6 +705,7 @@ namespace mRemoteNG.UI.Forms mMenViewConfig.Checked = !Windows.ConfigForm.IsHidden; mMenViewErrorsAndInfos.Checked = !Windows.ErrorsForm.IsHidden; mMenViewScreenshotManager.Checked = !Windows.ScreenshotForm.IsHidden; + mMenViewMultiPuttyCommand.Checked = !Windows.SSHCommandPanel.IsHidden; mMenViewExtAppsToolbar.Checked = tsExternalTools.Visible; mMenViewQuickConnectToolbar.Checked = tsQuickConnect.Visible; @@ -783,6 +784,20 @@ namespace mRemoteNG.UI.Forms } } + private void mMenViewMultiPuttyCommand_Click(object sender, EventArgs e) + { + if (mMenViewMultiPuttyCommand.Checked == false) + { + Windows.SSHCommandPanel.Show(pnlDock); + mMenViewMultiPuttyCommand.Checked = true; + } + else + { + Windows.SSHCommandPanel.Hide(); + mMenViewMultiPuttyCommand.Checked = false; + } + } + private void mMenViewJumpToConnectionsConfig_Click(object sender, EventArgs e) { if (pnlDock.ActiveContent == Windows.TreePanel) diff --git a/mRemoteV1/UI/Window/SSHCommandWIndow.Designer.cs b/mRemoteV1/UI/Window/SSHCommandWIndow.Designer.cs new file mode 100644 index 00000000..5a8649de --- /dev/null +++ b/mRemoteV1/UI/Window/SSHCommandWIndow.Designer.cs @@ -0,0 +1,75 @@ +namespace mRemoteNG.UI.Window +{ + partial class SSHCommandWIndow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtSSHCommand = new System.Windows.Forms.RichTextBox(); + this.lstCommands = new System.Windows.Forms.ListBox(); + this.SuspendLayout(); + // + // txtSSHCommand + // + this.txtSSHCommand.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtSSHCommand.Location = new System.Drawing.Point(0, 0); + this.txtSSHCommand.MinimumSize = new System.Drawing.Size(0, 150); + this.txtSSHCommand.Name = "txtSSHCommand"; + this.txtSSHCommand.Size = new System.Drawing.Size(821, 532); + this.txtSSHCommand.TabIndex = 0; + this.txtSSHCommand.Text = ""; + this.txtSSHCommand.Enter += new System.EventHandler(this.txtSSHCommand_Enter); + this.txtSSHCommand.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtSSHCommand_KeyDown); + this.txtSSHCommand.KeyUp += new System.Windows.Forms.KeyEventHandler(this.txtSSHCommand_KeyUp); + // + // lstCommands + // + this.lstCommands.Dock = System.Windows.Forms.DockStyle.Right; + this.lstCommands.FormattingEnabled = true; + this.lstCommands.ItemHeight = 16; + this.lstCommands.Location = new System.Drawing.Point(701, 0); + this.lstCommands.Name = "lstCommands"; + this.lstCommands.Size = new System.Drawing.Size(120, 532); + this.lstCommands.TabIndex = 1; + this.lstCommands.Visible = false; + // + // SSHCommandWIndow + // + this.ClientSize = new System.Drawing.Size(821, 532); + this.Controls.Add(this.lstCommands); + this.Controls.Add(this.txtSSHCommand); + this.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Name = "SSHCommandWIndow"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.RichTextBox txtSSHCommand; + private System.Windows.Forms.ListBox lstCommands; + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Window/SSHCommandWIndow.cs b/mRemoteV1/UI/Window/SSHCommandWIndow.cs new file mode 100644 index 00000000..922f92fc --- /dev/null +++ b/mRemoteV1/UI/Window/SSHCommandWIndow.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.App; +using System.Collections; +using mRemoteNG.Connection; + +namespace mRemoteNG.UI.Window +{ + public partial class SSHCommandWIndow : BaseWindow + { + + public SSHCommandWIndow(DockContent panel) + { + InitializeComponent(); + + WindowType = WindowType.SSHCommandWindow; + DockPnl = panel; + + HideOnClose = true; + Icon = Resources.Screenshot_Icon; + Name = "SSHCommander"; + TabText = "Multi-SSH"; + Text = "Multi-SSH Commander"; + } + + #region Private Fields + private ArrayList processHandlers = new ArrayList(); + #endregion + + #region Public Methods + #region Event Handlers + private void SSHCommandWindow_Load(object sender, EventArgs e) + { + Control.CheckForIllegalCrossThreadCalls = false; + } + + #endregion + + private void txtSSHCommand_Enter(object sender, EventArgs e) + { + try + { + var connectionInfoList = Runtime.ConnectionTreeModel.GetRecursiveChildList(); + //.Where( node-> !(node is Container.ContainerInfo)); + var previouslyOpenedConnections = connectionInfoList.Where(item => item.OpenConnections.Count > 0); + + //var connectionInfoList = connectionTree.GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); + //var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); + //foreach (var connectionInfo in previouslyOpenedConnections) + //{ + // _connectionInitiator.OpenConnection(connectionInfo); + //} + + + + processHandlers.Clear(); + foreach (ConnectionInfo connection in previouslyOpenedConnections) + { + foreach (ProtocolBase _base in connection.OpenConnections) + { + if (_base.GetType().IsSubclassOf(typeof(PuttyBase))) + { + processHandlers.Add((PuttyBase)_base); + } + } + } + } + catch (Exception ex) + { + + } + } + + private void txtSSHCommand_KeyDown(object sender, KeyEventArgs e) + { + if (processHandlers.Count == 0) + { + e.SuppressKeyPress = true; + return; + } + + if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down) + { + e.SuppressKeyPress = true; + //string lastCommand = ""; + //if (lstCommands.SelectedIndex == lstCommands.Items.Count) + //{ + // lastCommand = lstCommands.Items[lstCommands.Items.Count].ToString(); + //} + + if (e.KeyCode == Keys.Up && lstCommands.SelectedIndex -1 > -1 && lstCommands.SelectedItem.ToString() == txtSSHCommand.Text) + { + lstCommands.SelectedIndex -= 1; + } + + if (e.KeyCode == Keys.Down && lstCommands.SelectedIndex + 1 < lstCommands.Items.Count) + { + lstCommands.SelectedIndex += 1; + } + + txtSSHCommand.Text = lstCommands.SelectedItem.ToString(); + txtSSHCommand.Select(txtSSHCommand.TextLength, 0); + } + + if (e.Control == true && e.KeyCode != Keys.V && e.Alt == false) + { + sendAllKey(NativeMethods.WM_KEYDOWN, e.KeyValue); + } + + if (e.KeyCode == Keys.Enter) + { + string strLine = txtSSHCommand.Text; + foreach (char chr1 in strLine) + { + sendAllKey(NativeMethods.WM_CHAR, Convert.ToByte(chr1)); + } + sendAllKey(NativeMethods.WM_KEYDOWN, 13); // Enter = char13 + } + } + + private void gotoEndOfText() + { + if (txtSSHCommand.Text.Trim() != "") + { + lstCommands.Items.Add(txtSSHCommand.Text.Trim()); + } + lstCommands.SelectedIndex = lstCommands.Items.Count - 1; + txtSSHCommand.Clear(); + } + + private void sendAllKey(int keyType, int keyData) + { + if (processHandlers.Count == 0) + { + return; + } + foreach (PuttyBase proc in processHandlers) + { + NativeMethods.PostMessage(proc.PuttyHandle, keyType, new IntPtr(keyData), new IntPtr(0)); + } + } + + private void txtSSHCommand_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + { + gotoEndOfText(); + } + } + } + #endregion +} diff --git a/mRemoteV1/UI/Window/SSHCommandWIndow.resx b/mRemoteV1/UI/Window/SSHCommandWIndow.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/mRemoteV1/UI/Window/SSHCommandWIndow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mRemoteV1/UI/WindowType.cs b/mRemoteV1/UI/WindowType.cs index 3b320aaa..6ee9f730 100644 --- a/mRemoteV1/UI/WindowType.cs +++ b/mRemoteV1/UI/WindowType.cs @@ -17,5 +17,6 @@ namespace mRemoteNG.UI PortScan = 14, UltraVNCSC = 16, ComponentsCheck = 17, + SSHCommandWindow = 18, } } \ No newline at end of file diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 3d2f5e95..9d62f44d 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -47,6 +47,12 @@ True + + References\AxInterop.MSTSCLib.dll + + + References\AxInterop.WFICALib.dll + ..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll True @@ -59,6 +65,10 @@ ..\packages\Geckofx45.45.0.22\lib\net40\Geckofx-Winforms.dll True + + References\Interop.WFICALib.dll + True + False @@ -488,6 +498,12 @@ Form + + Form + + + SSHCommandWIndow.cs + Form @@ -671,6 +687,9 @@ ScreenshotManagerWindow.cs Designer + + SSHCommandWIndow.cs + SSHTransferWindow.cs Designer @@ -1219,14 +1238,6 @@ aximp False - - {238F6F80-B8B4-11CF-8771-00A024541EE3} - 2 - 7 - 0 - aximp - False - {8C11EFA1-92C3-11D1-BC1E-00C04FA31489} 1 @@ -1235,14 +1246,6 @@ tlbimp False - - {238F6F80-B8B4-11CF-8771-00A024541EE3} - 2 - 7 - 0 - tlbimp - False -