diff --git a/.idea/.idea.SuperPutty/.idea/.gitignore b/.idea/.idea.SuperPutty/.idea/.gitignore new file mode 100644 index 00000000..e2c1af94 --- /dev/null +++ b/.idea/.idea.SuperPutty/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/projectSettingsUpdater.xml +/modules.xml +/contentModel.xml +/.idea.SuperPutty.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.SuperPutty/.idea/.name b/.idea/.idea.SuperPutty/.idea/.name new file mode 100644 index 00000000..2692a887 --- /dev/null +++ b/.idea/.idea.SuperPutty/.idea/.name @@ -0,0 +1 @@ +SuperPutty \ No newline at end of file diff --git a/.idea/.idea.SuperPutty/.idea/encodings.xml b/.idea/.idea.SuperPutty/.idea/encodings.xml new file mode 100644 index 00000000..df87cf95 --- /dev/null +++ b/.idea/.idea.SuperPutty/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.SuperPutty/.idea/indexLayout.xml b/.idea/.idea.SuperPutty/.idea/indexLayout.xml new file mode 100644 index 00000000..7b08163c --- /dev/null +++ b/.idea/.idea.SuperPutty/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.SuperPutty/.idea/vcs.xml b/.idea/.idea.SuperPutty/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/.idea.SuperPutty/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SuperPutty.sln.DotSettings.user b/SuperPutty.sln.DotSettings.user new file mode 100644 index 00000000..1dfbc813 --- /dev/null +++ b/SuperPutty.sln.DotSettings.user @@ -0,0 +1,3 @@ + + 1114112 + C:\Users\reggi\AppData\Local\JetBrains\BuildTools\MSBuild\Current\Bin\MSBuild.exe \ No newline at end of file diff --git a/SuperPutty/Scripting/Spsl.cs b/SuperPutty/Scripting/Spsl.cs index c0b71813..f540ca33 100644 --- a/SuperPutty/Scripting/Spsl.cs +++ b/SuperPutty/Scripting/Spsl.cs @@ -7,6 +7,9 @@ using log4net; using SuperPutty; using SuperPutty.Utils; +using SuperPutty.Data; +using IronPython.Hosting; +using Microsoft.Scripting.Hosting; namespace SuperPuTTY.Scripting { @@ -105,6 +108,55 @@ public static void BeginExecuteScript(ExecuteScriptEventArgs scriptArgs) } } + /// Create an Action for a given command (keyword) executed in the Python script + /// The keyword for the command (i.e. SENDLINE) + /// A object containing the script to execute + /// and parameters + public static Action CreatePythonCommandAction(string keyword, ExecuteScriptEventArgs scriptArgs) + { + void CommandAction(object line) + { + CommandData command; + TryParseScriptLine(keyword + " " + line, out command); + + if (command != null) + { + command.SendToTerminal(scriptArgs.Handle.ToInt32()); + } + } + + return (CommandAction); + } + + /// Execute a SPSL script Async + /// A object containing the script to execute + /// and parameters + /// The SessionData in which to execute in Python script + public static void BeginExecutePythonScript(ExecuteScriptEventArgs scriptArgs, SessionData session) + { + new System.Threading.Thread(delegate() + { + ScriptEngine engine = Python.CreateEngine(); + + // Create a ScriptSource to encapsulate our program and a scope in which it runs + ScriptSource source = engine.CreateScriptSourceFromString(scriptArgs.Script); + ScriptScope scope = engine.CreateScope(); + foreach (SPSLFunction spslFunction in keywords) + { + scope.SetVariable(spslFunction.command, + CreatePythonCommandAction(spslFunction.command, scriptArgs)); + } + + if (session != null) + { + scope.SetVariable("Session", session); + } + + // Execute the script in 'scope' + source.Execute(scope); + }).Start(); + } + /// Find Valid spsl script commands from lookup table and retrieve the Function to execute /// the SPSL command to lookup /// The Function associated with the command or null of the command is invalid diff --git a/SuperPutty/SuperPuTTY.cs b/SuperPutty/SuperPuTTY.cs index 8693d535..84618fdb 100644 --- a/SuperPutty/SuperPuTTY.cs +++ b/SuperPutty/SuperPuTTY.cs @@ -529,8 +529,15 @@ public static ctlPuttyPanel OpenProtoSession(SessionData session) if (!String.IsNullOrEmpty(script)) { ExecuteScriptEventArgs scriptArgs = new ExecuteScriptEventArgs() { Script = script, Handle = panel.AppPanel.AppWindowHandle }; - SPSL.BeginExecuteScript(scriptArgs); - } + + if (scriptArgs.IsPython) + { + SPSL.BeginExecutePythonScript(scriptArgs, session); + } + else + { + SPSL.BeginExecuteScript(scriptArgs); + } } } } catch (InvalidOperationException ex) { diff --git a/SuperPutty/SuperPutty.csproj b/SuperPutty/SuperPutty.csproj index 600daca0..96f318a5 100644 --- a/SuperPutty/SuperPutty.csproj +++ b/SuperPutty/SuperPutty.csproj @@ -10,7 +10,7 @@ Properties SuperPutty SuperPutty - v4.5 + v4.5.2 512 @@ -33,6 +33,7 @@ 1.0.0.%2a false true + 9 true @@ -65,9 +66,37 @@ app.manifest + + ..\packages\IronPython.2.7.11\lib\net45\IronPython.dll + True + + + ..\packages\IronPython.2.7.11\lib\net45\IronPython.Modules.dll + True + + + ..\packages\IronPython.2.7.11\lib\net45\IronPython.SQLite.dll + True + + + ..\packages\IronPython.2.7.11\lib\net45\IronPython.Wpf.dll + True + ..\packages\log4net.2.0.13\lib\net45\log4net.dll + + ..\packages\DynamicLanguageRuntime.1.3.0\lib\net45\Microsoft.Dynamic.dll + True + + + ..\packages\DynamicLanguageRuntime.1.3.0\lib\net45\Microsoft.Scripting.dll + True + + + ..\packages\DynamicLanguageRuntime.1.3.0\lib\net45\Microsoft.Scripting.Metadata.dll + True + ..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll diff --git a/SuperPutty/dlgScriptEditor.cs b/SuperPutty/dlgScriptEditor.cs index 82dcc2e3..274c1cf5 100644 --- a/SuperPutty/dlgScriptEditor.cs +++ b/SuperPutty/dlgScriptEditor.cs @@ -80,7 +80,7 @@ public class ExecuteScriptEventArgs : EventArgs { /// A string containing a list of commands to be sent to open terminal sessions public string Script { get; set; } - /// True if the script should be handled by script parser + /// True if the script should be handled by SPSL script parser public bool IsSPSL { get { @@ -92,6 +92,18 @@ public bool IsSPSL { } } + /// True if the script should be handled by Python script parser + public bool IsPython { + get + { + if (!string.IsNullOrEmpty(this.Script) + && this.Script.StartsWith("#!/bin/python")) + return true; + else + return false; + } + } + /// If set to the handle of a window, script will be restricted to the specified session only. public IntPtr Handle { get; set; } } diff --git a/SuperPutty/frmSuperPutty.cs b/SuperPutty/frmSuperPutty.cs index 9ec784e0..0e3d29eb 100644 --- a/SuperPutty/frmSuperPutty.cs +++ b/SuperPutty/frmSuperPutty.cs @@ -1209,8 +1209,9 @@ private int TrySendCommandsFromToolbar(bool saveHistory) /// Send commands to open sessions /// The object containing text and or keyboard commands /// If True, save the history in the command toolbar combobox + /// If True, send the command to the Python scripting engine /// The number terminals commands have been sent to - private int TrySendCommandsFromToolbar(CommandData command, bool saveHistory) + private int TrySendCommandsFromToolbar(CommandData command, bool saveHistory, bool isPythonScript = false) { int sent = 0; @@ -1231,8 +1232,17 @@ private int TrySendCommandsFromToolbar(CommandData command, bool saveHistory) int handle = hPtr.ToInt32(); //Log.InfoFormat("SendCommand: session={0}, command=[{1}], handle={2}", panel.Session.SessionId, command, handle); - command.SendToTerminal(handle); - + if (isPythonScript) + { + SPSL.BeginExecutePythonScript( + new ExecuteScriptEventArgs() { Script = command.Command, Handle = hPtr }, + panel.Session); + } + else + { + command.SendToTerminal(handle); + } + sent++; } } @@ -1904,7 +1914,11 @@ private void Editor_ScriptReady(object sender, ExecuteScriptEventArgs e) } }).Start(); } - else // Not a spsl script + else if (e.IsPython) + { + TrySendCommandsFromToolbar(new CommandData(e.Script), false, true); + } + else // Not a spsl or Python script { foreach (string line in scriptlines) { diff --git a/SuperPutty/packages.config b/SuperPutty/packages.config index dec8053d..013cad2c 100644 --- a/SuperPutty/packages.config +++ b/SuperPutty/packages.config @@ -2,6 +2,8 @@ + + diff --git a/SuperPuttyUnitTests/SuperPuttyUnitTests.csproj b/SuperPuttyUnitTests/SuperPuttyUnitTests.csproj index db0887cc..6b7d1c7e 100644 --- a/SuperPuttyUnitTests/SuperPuttyUnitTests.csproj +++ b/SuperPuttyUnitTests/SuperPuttyUnitTests.csproj @@ -10,7 +10,7 @@ Properties SuperPuttyUnitTests SuperPuttyUnitTests - v4.5 + v4.5.2 512