From b77bbd5aec32cac1a753a1169a1ac24c61a4ac87 Mon Sep 17 00:00:00 2001 From: Frank Skare Date: Tue, 19 Mar 2019 09:56:05 +0100 Subject: [PATCH] 1.3 --- README.md | 13 ++- mpv.net/PowerShellScript.cs | 124 +++++++++++++++++++++++ mpv.net/Properties/AssemblyInfo.cs | 4 +- mpv.net/{PyScript.cs => PythonScript.cs} | 4 +- mpv.net/mp.cs | 33 +++--- mpv.net/mpv.net.csproj | 7 +- mpv.net/packages.config | 4 + 7 files changed, 171 insertions(+), 18 deletions(-) create mode 100644 mpv.net/PowerShellScript.cs rename mpv.net/{PyScript.cs => PythonScript.cs} (91%) create mode 100644 mpv.net/packages.config diff --git a/README.md b/README.md index 1b3ecb6..6fe031e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ mpv manual: https://mpv.io/manual/master/ - Customizable context menu defined in the same file as the keybindings - Addon API for .NET languages -- Python scripting implemented with IronPython +- 5 different scripting languages are supported, Python scripting implemented with IronPython, C# implemented with CS-Script, Lua and JavaScript implemented in libmpv and PowerShell - C# scripting implemented with CS-Script - mpv's OSC, IPC, Lua/JS, conf files and more @@ -82,6 +82,17 @@ def add_zero(val): mp.register_event("seek", seek) # or use: mp.Seek += seek ``` +### PowerShell Scripting + +A simple PowerShell script located at: C:\Users\user\AppData\Roaming\mpv\scripts + +Please note that PowerShell don't allow assigning to events and mpv.net uses as workaround the script filename. + +``` +$position = [mp]::get_property_number("time-pos"); +[mp]::commandv("show-text", $position.ToString() + " seconds") +``` + ### Changes ### not yet released diff --git a/mpv.net/PowerShellScript.cs b/mpv.net/PowerShellScript.cs new file mode 100644 index 0000000..b407695 --- /dev/null +++ b/mpv.net/PowerShellScript.cs @@ -0,0 +1,124 @@ +using System; +using System.IO; +using System.Threading; +using System.Management.Automation.Runspaces; + +using static mpvnet.StaticUsing; +using System.Reflection; +using System.Threading.Tasks; + +namespace mpvnet +{ + public class PowerShellScript + { + public static object Execute(string code, string[] parameters) + { + using (Runspace runspace = RunspaceFactory.CreateRunspace()) + { + runspace.ApartmentState = ApartmentState.STA; + runspace.ThreadOptions = PSThreadOptions.UseCurrentThread; + runspace.Open(); + + using (Pipeline pipeline = runspace.CreatePipeline()) + { + pipeline.Commands.AddScript( +@"Using namespace mpvnet; +Using namespace System; +[System.Reflection.Assembly]::LoadWithPartialName(""mpvnet"")"); + + pipeline.Commands.AddScript(code); + + try + { + var ret = pipeline.Invoke(parameters); + + if (ret.Count > 0) + return ret[0]; + } + catch (Exception ex) + { + try + { + using (Pipeline pipeline2 = runspace.CreatePipeline()) + { + pipeline2.Commands.AddScript("$PSVersionTable.PSVersion.Major * 10 +" + + "$PSVersionTable.PSVersion.Minor"); + + if (Convert.ToInt32(pipeline2.Invoke()[0].ToString()) < 51) + throw new Exception(); + } + } + catch + { + MsgError("PowerShell Setup Problem\r\n\r\nEnsure you have at least PowerShell 5.1 installed."); + return null; + } + MsgError(ex.ToString()); + } + } + } + return null; + } + + public static void Init(string filePath) + { + foreach (var eventInfo in typeof(mp).GetEvents()) + { + if (eventInfo.Name.ToLower() == + Path.GetFileNameWithoutExtension(filePath).ToLower().Replace("-", "")) + { + PowerShellEventObject eventObject = new PowerShellEventObject(); + MethodInfo mi; + eventObject.FilePath = filePath; + + if (eventInfo.EventHandlerType == typeof(Action)) + { + mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke)); + } + else if (eventInfo.EventHandlerType == typeof(Action)) + { + mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFileEventMode)); + } + else if (eventInfo.EventHandlerType == typeof(Action)) + { + mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings)); + } + else + throw new Exception(); + + eventObject.EventInfo = eventInfo; + Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, eventObject, mi); + eventObject.Delegate = handler; + eventInfo.AddEventHandler(eventObject, handler); + } + } + } + } + + public class PowerShellEventObject + { + public EventInfo EventInfo { get; set; } + public Delegate Delegate { get; set; } + public string FilePath { get; set; } + + public void Invoke() + { + Task.Run(() => { PowerShellScript.Execute(File.ReadAllText(FilePath), new string[] { }); }); + } + + public void InvokeEndFileEventMode(EndFileEventMode arg) + { + Task.Run(() => + { + PowerShellScript.Execute(File.ReadAllText(FilePath), new string[] { arg.ToString() }); + }); + } + + public void InvokeStrings(string[] args) + { + Task.Run(() => { + PowerShellScript.Execute(File.ReadAllText(FilePath), args); + }); + } + } +} \ No newline at end of file diff --git a/mpv.net/Properties/AssemblyInfo.cs b/mpv.net/Properties/AssemblyInfo.cs index a7f8ed8..e7eabdd 100644 --- a/mpv.net/Properties/AssemblyInfo.cs +++ b/mpv.net/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.0.0")] -[assembly: AssemblyFileVersion("1.2.0.0")] +[assembly: AssemblyVersion("1.3.0.0")] +[assembly: AssemblyFileVersion("1.3.0.0")] diff --git a/mpv.net/PyScript.cs b/mpv.net/PythonScript.cs similarity index 91% rename from mpv.net/PyScript.cs rename to mpv.net/PythonScript.cs index e746a1b..1f37e83 100644 --- a/mpv.net/PyScript.cs +++ b/mpv.net/PythonScript.cs @@ -7,12 +7,12 @@ using static mpvnet.StaticUsing; namespace mpvnet { - public class PyScript + public class PythonScript { ScriptEngine engine; ScriptScope scope; - public PyScript(string code) + public PythonScript(string code) { try { diff --git a/mpv.net/mp.cs b/mpv.net/mp.cs index 41f0e6b..6b702a5 100644 --- a/mpv.net/mp.cs +++ b/mpv.net/mp.cs @@ -60,7 +60,7 @@ namespace mpvnet public static string mpvConfFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\"; public static string InputConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\input.conf"; public static string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf"; - public static List PyScripts { get; } = new List(); + public static List PythonScripts { get; } = new List(); public static bool IsShutdownComplete { get; set; } private static Dictionary _mpvConv; @@ -122,10 +122,19 @@ namespace mpvnet foreach (var scriptPath in startupScripts) if (Path.GetExtension(scriptPath) == ".py") - PyScripts.Add(new PyScript(File.ReadAllText(scriptPath))); + PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath))); - foreach(var scriptPath in Directory.GetFiles(mp.mpvConfFolderPath + "scripts", "*.py")) - PyScripts.Add(new PyScript(File.ReadAllText(scriptPath))); + foreach (var scriptPath in startupScripts) + if (Path.GetExtension(scriptPath) == ".ps1") + PowerShellScript.Init(scriptPath); + + foreach (var scriptPath in Directory.GetFiles(mp.mpvConfFolderPath + "Scripts")) + { + if (Path.GetExtension(scriptPath) == ".py") + PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath))); + else if (Path.GetExtension(scriptPath) == ".ps1") + PowerShellScript.Init(scriptPath); + } } public static void EventLoop() @@ -251,7 +260,7 @@ namespace mpvnet } } - public class EventObject + public class PythonEventObject { public PyRT.PythonFunction PythonFunction { get; set; } public EventInfo EventInfo { get; set; } @@ -273,7 +282,7 @@ namespace mpvnet } } - private static List EventObjects = new List(); + private static List PythonEventObjects = new List(); public static void register_event(string name, PyRT.PythonFunction pyFunc) { @@ -281,22 +290,22 @@ namespace mpvnet { if (eventInfo.Name.ToLower() == name.Replace("-", "")) { - EventObject eventObject = new EventObject(); - EventObjects.Add(eventObject); + PythonEventObject eventObject = new PythonEventObject(); + PythonEventObjects.Add(eventObject); eventObject.PythonFunction = pyFunc; MethodInfo mi; if (eventInfo.EventHandlerType == typeof(Action)) { - mi = eventObject.GetType().GetMethod(nameof(EventObject.Invoke)); + mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.Invoke)); } else if (eventInfo.EventHandlerType == typeof(Action)) { - mi = eventObject.GetType().GetMethod(nameof(EventObject.InvokeEndFileEventMode)); + mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.InvokeEndFileEventMode)); } else if (eventInfo.EventHandlerType == typeof(Action)) { - mi = eventObject.GetType().GetMethod(nameof(EventObject.InvokeStrings)); + mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.InvokeStrings)); } else throw new Exception(); @@ -311,7 +320,7 @@ namespace mpvnet public static void unregister_event(PyRT.PythonFunction pyFunc) { - foreach (var eventObjects in EventObjects) + foreach (var eventObjects in PythonEventObjects) if (eventObjects.PythonFunction == pyFunc) eventObjects.EventInfo.RemoveEventHandler(eventObjects, eventObjects.Delegate); } diff --git a/mpv.net/mpv.net.csproj b/mpv.net/mpv.net.csproj index 49a169b..c5bde98 100644 --- a/mpv.net/mpv.net.csproj +++ b/mpv.net/mpv.net.csproj @@ -122,6 +122,9 @@ + + ..\packages\Microsoft.PowerShell.5.ReferenceAssemblies.1.1.0\lib\net4\System.Management.Automation.dll + @@ -137,7 +140,8 @@ True Resources.resx - + + @@ -164,6 +168,7 @@ Resources.Designer.cs + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/mpv.net/packages.config b/mpv.net/packages.config new file mode 100644 index 0000000..f8c2131 --- /dev/null +++ b/mpv.net/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file