From 63ee598ebdcc990d1f976bc669b341ec65be76d6 Mon Sep 17 00:00:00 2001 From: Frank Skare Date: Sun, 16 Jun 2019 10:00:14 +0200 Subject: [PATCH] support added to force single instance --- Changelog.md | 3 ++ mpv.net/Misc/Command.cs | 12 ++++--- mpv.net/Misc/Misc.cs | 22 +++++++++---- mpv.net/Misc/Program.cs | 47 ++++++++++++++++++++++++--- mpv.net/Resources/inputConf.txt | 5 +-- mpv.net/Resources/mpvNetConfToml.txt | 11 ++++++- mpv.net/WPF/EverythingWindow.xaml.cs | 2 +- mpv.net/WinForms/MainForm.cs | 48 +++++++++++++++++++++------- mpv.net/mpv/mp.cs | 8 ++--- 9 files changed, 122 insertions(+), 36 deletions(-) diff --git a/Changelog.md b/Changelog.md index b1cc384..4878a9e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,9 @@ - the help and layout in the config editor was improved - clipboard monitoring for URLs can be disabled in the settings - internal refactoring that might break features, scripts or extensions +- the context menu has a new feature: Open > Add files to playlist, + it appends files to the playlist [(Default binding)](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L34) +- a new feature was added to force using a single mpv.net process instance ### 4.1 diff --git a/mpv.net/Misc/Command.cs b/mpv.net/Misc/Command.cs index 4bec171..057477b 100644 --- a/mpv.net/Misc/Command.cs +++ b/mpv.net/Misc/Command.cs @@ -7,6 +7,8 @@ using System.Reflection; using System.Windows.Forms; using System.Windows.Interop; +using VB = Microsoft.VisualBasic; + namespace mpvnet { public class Command @@ -46,7 +48,7 @@ namespace mpvnet MainForm.Instance.Invoke(new Action(() => { using (var d = new OpenFileDialog() { Multiselect = true }) if (d.ShowDialog() == DialogResult.OK) - mp.LoadFiles(d.FileNames); + mp.Load(d.FileNames); })); } @@ -181,9 +183,9 @@ namespace mpvnet public static void execute_mpv_command(string[] args) { MainForm.Instance.Invoke(new Action(() => { - string command = Microsoft.VisualBasic.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "RecentExecutedCommand")); + string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString(App.RegPath, "RecentExecutedCommand")); if (string.IsNullOrEmpty(command)) return; - RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "RecentExecutedCommand", command); + RegistryHelp.SetObject(App.RegPath, "RecentExecutedCommand", command); mp.command_string(command, false); })); } @@ -191,9 +193,9 @@ namespace mpvnet public static void open_url(string[] args) { MainForm.Instance.Invoke(new Action(() => { - string command = Microsoft.VisualBasic.Interaction.InputBox("Enter URL to be opened."); + string command = VB.Interaction.InputBox("Enter URL to be opened."); if (string.IsNullOrEmpty(command)) return; - mp.LoadFiles(command); + mp.Load(command); })); } diff --git a/mpv.net/Misc/Misc.cs b/mpv.net/Misc/Misc.cs index 3e74314..6ee0a48 100644 --- a/mpv.net/Misc/Misc.cs +++ b/mpv.net/Misc/Misc.cs @@ -18,6 +18,7 @@ namespace mpvnet public class App { public static string ConfFilePath { get; } = mp.ConfFolder + "\\mpvnet.conf"; + public static string RegPath { get; } = "HKCU\\Software\\" + Application.ProductName; public static string ClipboardMonitoring { get; set; } = "yes"; public static string[] VideoTypes { get; } = "mkv mp4 mpg avi mov webm vob wmv flv avs 264 h264 asf webm mpeg mpv y4m avc hevc 265 h265 m2v m2ts vpy mts m4v".Split(' '); @@ -25,6 +26,7 @@ namespace mpvnet public static string[] SubtitleTypes { get; } = "srt ass idx sup ttxt ssa smi".Split(' '); public static string DarkMode { get; set; } = "always"; + public static string ProcessInstance { get; set; } = "single"; public static bool IsDarkMode { get => (DarkMode == "system" && Sys.IsDarkTheme) || DarkMode == "always"; @@ -57,12 +59,9 @@ namespace mpvnet { switch (name) { - case "dark-mode": - DarkMode = value; - break; - case "clipboard-monitoring": - ClipboardMonitoring = value; - break; + case "clipboard-monitoring": ClipboardMonitoring = value; break; + case "process-instance": ProcessInstance = value; break; + case "dark-mode": DarkMode = value; break; } } @@ -363,4 +362,15 @@ namespace mpvnet Math.Abs(screenPos.Y - Control.MousePosition.Y) > 10; } } + + public class SingleProcess + { + public static int Message { get; } = RegisterWindowMessage("mpvnet_IPC"); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern int RegisterWindowMessage(string id); + + [DllImport("user32.dll")] + public static extern bool AllowSetForegroundWindow(int dwProcessId); + } } \ No newline at end of file diff --git a/mpv.net/Misc/Program.cs b/mpv.net/Misc/Program.cs index fb44ca8..d2911f6 100644 --- a/mpv.net/Misc/Program.cs +++ b/mpv.net/Misc/Program.cs @@ -1,5 +1,10 @@ using System; using System.Windows.Forms; +using System.Linq; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Diagnostics; namespace mpvnet { @@ -8,15 +13,43 @@ namespace mpvnet [STAThread] static void Main() { + Mutex mutex = new Mutex(true, "mpvnetProcessInstance", out bool isFirst); + try { - string[] args = Environment.GetCommandLineArgs(); + string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray(); - if (args.Length == 3 && args[1] == "--reg-file-assoc") + if (args.Length == 2 && args[0] == "--reg-file-assoc") { - if (args[2] == "audio") FileAssociation.Register(App.AudioTypes); - if (args[2] == "video") FileAssociation.Register(App.VideoTypes); - if (args[2] == "unreg") FileAssociation.Unregister(); + if (args[1] == "audio") FileAssociation.Register(App.AudioTypes); + if (args[1] == "video") FileAssociation.Register(App.VideoTypes); + if (args[1] == "unreg") FileAssociation.Unregister(); + return; + } + + App.Init(); + + if ((App.ProcessInstance == "single" || App.ProcessInstance == "queue") && !isFirst) + { + List files = new List(); + + foreach (string arg in args) + if (!arg.StartsWith("--") && (File.Exists(arg) || arg == "-" || arg.StartsWith("http"))) + files.Add(arg); + + if (files.Count > 0) + RegistryHelp.SetObject(App.RegPath, "ShellFiles", files.ToArray()); + + RegistryHelp.SetObject(App.RegPath, "ProcessInstanceMode", App.ProcessInstance); + + foreach(Process process in Process.GetProcessesByName("mpvnet")) + { + try { + SingleProcess.AllowSetForegroundWindow(process.Id); + Native.SendMessage(process.MainWindowHandle, SingleProcess.Message, IntPtr.Zero, IntPtr.Zero); + } catch {} + } + return; } @@ -28,6 +61,10 @@ namespace mpvnet { Msg.ShowException(ex); } + finally + { + mutex.Dispose(); + } } } } \ No newline at end of file diff --git a/mpv.net/Resources/inputConf.txt b/mpv.net/Resources/inputConf.txt index bdb36e2..40eeacb 100644 --- a/mpv.net/Resources/inputConf.txt +++ b/mpv.net/Resources/inputConf.txt @@ -26,12 +26,13 @@ o script-message mpv.net open-files #menu: Open > Open Files... u script-message mpv.net open-url #menu: Open > Open URL... - Ctrl+S script-message mpv.net show-media-search #menu: Open > Show media search... _ ignore #menu: Open > - Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files... Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files... _ ignore #menu: Open > - _ script-message mpv.net add-files-to-playlist #menu: Open > Add files to playlist... + Ctrl+S script-message mpv.net show-media-search #menu: Open > Show media search... + _ ignore #menu: Open > - _ ignore #menu: Open > Recent _ ignore #menu: - @@ -138,7 +139,7 @@ F8 show-text ${playlist} 5000 #menu: View > Show Playlist F9 show-text ${track-list} 5000 #menu: View > Show Audio/Video/Subtitle List - Ctrl+c script-message mpv.net show-conf-editor #menu: Settings > Show Config Editor + c script-message mpv.net show-conf-editor #menu: Settings > Show Config Editor Ctrl+i script-message mpv.net show-input-editor #menu: Settings > Show Input Editor Ctrl+f script-message mpv.net open-conf-folder #menu: Settings > Open Config Folder diff --git a/mpv.net/Resources/mpvNetConfToml.txt b/mpv.net/Resources/mpvNetConfToml.txt index c0ffa89..8dab47d 100644 --- a/mpv.net/Resources/mpvNetConfToml.txt +++ b/mpv.net/Resources/mpvNetConfToml.txt @@ -13,4 +13,13 @@ default = "yes" filter = "mpv.net" help = "Monitors the clipboard for URLs to play." options = [{ name = "yes" }, - { name = "no" }] \ No newline at end of file + { name = "no" }] + +[[settings]] +name = "process-instance" +default = "single" +filter = "mpv.net" +help = "Defines if more then one mpv.net process is allowed." +options = [{ name = "multi", help = "Create a new process everytime the shell starts mpv.net" }, + { name = "single", help = "Force a single process everytime the shell starts mpv.net" }, + { name = "queue", help = "Force a single process and add files to playlist" }] \ No newline at end of file diff --git a/mpv.net/WPF/EverythingWindow.xaml.cs b/mpv.net/WPF/EverythingWindow.xaml.cs index f92035e..d384ac5 100644 --- a/mpv.net/WPF/EverythingWindow.xaml.cs +++ b/mpv.net/WPF/EverythingWindow.xaml.cs @@ -113,7 +113,7 @@ namespace mpvnet void Execute() { if (ListView.SelectedItem != null) - mp.LoadFiles(ListView.SelectedItem as string); + mp.Load(ListView.SelectedItem as string); Keyboard.Focus(FilterTextBox); } diff --git a/mpv.net/WinForms/MainForm.cs b/mpv.net/WinForms/MainForm.cs index 5b0577d..5fef005 100644 --- a/mpv.net/WinForms/MainForm.cs +++ b/mpv.net/WinForms/MainForm.cs @@ -35,13 +35,12 @@ namespace mpvnet Msg.SupportURL = "https://github.com/stax76/mpv.net#support"; Instance = this; WPF.WPF.Init(); - App.Init(); System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; Hwnd = Handle; MinimumSize = new Size(FontHeight * 16, FontHeight * 9); Text += " " + Application.ProductVersion; - object recent = RegistryHelp.GetObject("HKCU\\Software\\" + Application.ProductName, "Recent"); + object recent = RegistryHelp.GetObject(App.RegPath, "Recent"); if (recent is string[] r) RecentFiles = new List(r); @@ -153,7 +152,7 @@ namespace mpvnet recent.DropDownItems.Clear(); foreach (string path in RecentFiles) - MenuItem.Add(recent.DropDownItems, path, () => mp.LoadFiles(path)); + MenuItem.Add(recent.DropDownItems, path, () => mp.Load(path)); recent.DropDownItems.Add(new ToolStripSeparator()); MenuItem mi = new MenuItem("Clear List"); @@ -376,6 +375,31 @@ namespace mpvnet m.Result = new IntPtr(1); return; } + + if (m.Msg == SingleProcess.Message) + { + object filesObject = RegistryHelp.GetObject(App.RegPath, "ShellFiles"); + + if (filesObject is string[] files) + { + switch (RegistryHelp.GetString(App.RegPath, "ProcessInstanceMode")) + { + case "single": + mp.Load(files); + break; + case "queue": + foreach (string file in files) + if (File.Exists(file)) + mp.commandv("loadfile", file, "append"); + break; + } + } + + RegistryHelp.RemoveValue(App.RegPath, "ShellFiles"); + Activate(); + return; + } + base.WndProc(ref m); } @@ -390,9 +414,9 @@ namespace mpvnet { base.OnDragDrop(e); if (e.Data.GetDataPresent(DataFormats.FileDrop)) - mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]); + mp.Load(e.Data.GetData(DataFormats.FileDrop) as String[]); if (e.Data.GetDataPresent(DataFormats.Text)) - mp.LoadFiles(e.Data.GetData(DataFormats.Text).ToString()); + mp.Load(e.Data.GetData(DataFormats.Text).ToString()); } protected override void OnMouseDown(MouseEventArgs e) @@ -474,7 +498,7 @@ namespace mpvnet BuildMenu(); ContextMenuStrip = ContextMenu; IgnoreDpiChanged = false; - CheckURL(); + CheckURLinClipboard(); } protected override void OnResize(EventArgs e) @@ -486,7 +510,7 @@ namespace mpvnet protected override void OnFormClosed(FormClosedEventArgs e) { base.OnFormClosed(e); - RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "Recent", RecentFiles.ToArray()); + RegistryHelp.SetObject(App.RegPath, "Recent", RecentFiles.ToArray()); mp.commandv("quit"); mp.AutoResetEvent.WaitOne(3000); } @@ -500,20 +524,20 @@ namespace mpvnet protected override void OnActivated(EventArgs e) { base.OnActivated(e); - CheckURL(); + CheckURLinClipboard(); } - void CheckURL() + void CheckURLinClipboard() { if (App.ClipboardMonitoring != "yes") return; string clipboard = Clipboard.GetText(); - if (clipboard.StartsWith("http") && RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "LastURL") != clipboard && Visible) + if (clipboard.StartsWith("http") && RegistryHelp.GetString(App.RegPath, "LastURL") != clipboard && Visible) { - RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "LastURL", clipboard); + RegistryHelp.SetObject(App.RegPath, "LastURL", clipboard); if (Msg.ShowQuestion("Play URL?", clipboard) == MsgResult.OK) - mp.LoadFiles(clipboard); + mp.Load(clipboard); } } } diff --git a/mpv.net/mpv/mp.cs b/mpv.net/mpv/mp.cs index d912387..db2680b 100644 --- a/mpv.net/mpv/mp.cs +++ b/mpv.net/mpv/mp.cs @@ -531,15 +531,15 @@ namespace mpvnet foreach (string i in args) { - if (!i.StartsWith("--") && File.Exists(i) || i == "-" || i.StartsWith("http")) + if (!i.StartsWith("--") && (File.Exists(i) || i == "-" || i.StartsWith("http"))) { files.Add(i); if (i.StartsWith("http")) - RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "LastURL", i); + RegistryHelp.SetObject(App.RegPath, "LastURL", i); } } - mp.LoadFiles(files.ToArray()); + mp.Load(files.ToArray()); foreach (string i in args) { @@ -557,7 +557,7 @@ namespace mpvnet } } - public static void LoadFiles(params string[] files) + public static void Load(params string[] files) { if (files is null || files.Length == 0) return; HideLogo();