diff --git a/QuickLook/App.xaml.cs b/QuickLook/App.xaml.cs
index b0ecd3b..85efc4c 100644
--- a/QuickLook/App.xaml.cs
+++ b/QuickLook/App.xaml.cs
@@ -1,10 +1,10 @@
using System;
-using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Threading;
using System.Windows;
-using QuickLook.Helpers;
+using System.Windows.Threading;
namespace QuickLook
{
@@ -16,9 +16,9 @@ namespace QuickLook
public static readonly bool Is64Bit = Environment.Is64BitProcess;
public static readonly string AppFullPath = Assembly.GetExecutingAssembly().Location;
public static readonly string AppPath = Path.GetDirectoryName(AppFullPath);
- public static bool RunningAsViewer;
- private static bool _duplicated;
+ private bool _isFirstInstance;
+ private Mutex _isRunning;
protected override void OnStartup(StartupEventArgs e)
{
@@ -27,7 +27,7 @@ namespace QuickLook
MessageBox.Show(((Exception) args.ExceptionObject).Message + Environment.NewLine +
((Exception) args.ExceptionObject).StackTrace);
- Current.Shutdown();
+ Shutdown();
};
base.OnStartup(e);
@@ -35,65 +35,60 @@ namespace QuickLook
private void Application_Startup(object sender, StartupEventArgs e)
{
- if (e.Args.Any())
- if (Directory.Exists(e.Args.First()) || File.Exists(e.Args.First()))
- RunAsViewer(e);
+ EnsureFirstInstance();
+
+ if (!_isFirstInstance)
+ {
+ // second instance: preview this file
+ if (e.Args.Any() && (Directory.Exists(e.Args.First()) || File.Exists(e.Args.First())))
+ RemoteCallShowPreview(e);
+ // second instance: duplicate
else
- RunAsListener(e);
- else
- RunAsListener(e);
- }
+ MessageBox.Show("QuickLook is already running in the background.");
- private void RunAsViewer(StartupEventArgs e)
- {
- RunningAsViewer = true;
-
- var runningPid = PidHelper.GetRunningInstance();
- if (runningPid != -1)
- {
- Process.GetProcessById(runningPid).Kill();
-
- Current.Shutdown();
+ Shutdown();
return;
}
- PidHelper.WritePid();
+ RunListener(e);
- ViewWindowManager.GetInstance().InvokeViewer(e.Args.First());
+ // second instance: run and preview this file
+ if (e.Args.Any() && (Directory.Exists(e.Args.First()) || File.Exists(e.Args.First())))
+ RemoteCallShowPreview(e);
}
- private void RunAsListener(StartupEventArgs e)
+ private void RemoteCallShowPreview(StartupEventArgs e)
{
- RunningAsViewer = false;
-
- if (PidHelper.GetRunningInstance() != -1)
- {
- _duplicated = true;
-
- MessageBox.Show("QuickLook is already running in the background.");
-
- Current.Shutdown();
- return;
- }
-
- PidHelper.WritePid();
+ PipeServerManager.SendMessage(e.Args.First());
+ }
+ private void RunListener(StartupEventArgs e)
+ {
TrayIconManager.GetInstance();
if (!e.Args.Contains("/autorun"))
TrayIconManager.GetInstance().ShowNotification("", "QuickLook is running in the background.");
PluginManager.GetInstance();
-
BackgroundListener.GetInstance();
+ PipeServerManager.GetInstance().MessageReceived +=
+ (msg, ea) => Dispatcher.BeginInvoke(
+ new Action(() => ViewWindowManager.GetInstance().InvokeViewer(msg as string)),
+ DispatcherPriority.ApplicationIdle);
}
private void App_OnExit(object sender, ExitEventArgs e)
{
- TrayIconManager.GetInstance().Dispose();
- BackgroundListener.GetInstance().Dispose();
+ if (_isFirstInstance)
+ {
+ PipeServerManager.GetInstance().Dispose();
+ TrayIconManager.GetInstance().Dispose();
+ BackgroundListener.GetInstance().Dispose();
+ }
+ }
- if (!_duplicated)
- PidHelper.DeletePid();
+ private void EnsureFirstInstance()
+ {
+ _isRunning = new Mutex(true, "QuickLook.App.Mutex", out _isFirstInstance);
}
}
}
\ No newline at end of file
diff --git a/QuickLook/Helpers/PidHelper.cs b/QuickLook/Helpers/PidHelper.cs
deleted file mode 100644
index b646dba..0000000
--- a/QuickLook/Helpers/PidHelper.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System.Diagnostics;
-using System.IO;
-
-namespace QuickLook.Helpers
-{
- internal static class PidHelper
- {
- private static FileStream _pidLocker;
-
- private static readonly string PidListener =
- Path.Combine(Path.GetTempPath(), "QuickLook.App.Listener.D6EC3F8DDF6B.pid");
-
- private static readonly string PidViewer =
- Path.Combine(Path.GetTempPath(), "QuickLook.App.Viewer.A6FA53E93515.pid");
-
- internal static int GetRunningInstance()
- {
- var pid = App.RunningAsViewer ? PidViewer : PidListener;
-
- if (!File.Exists(pid))
- return -1;
-
- var ppid = -1;
- using (var file = File.Open(pid, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
- using (var sr = new StreamReader(file))
- {
- int.TryParse(sr.ReadToEnd(), out ppid);
- }
-
- try
- {
- Process.GetProcessById(ppid);
- }
- catch
- {
- return -1;
- }
-
- return ppid;
- }
-
- internal static void WritePid()
- {
- var pidFile = App.RunningAsViewer ? PidViewer : PidListener;
-
- File.WriteAllText(pidFile, Process.GetCurrentProcess().Id.ToString());
-
- _pidLocker = File.Open(pidFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
- }
-
- internal static void DeletePid()
- {
- _pidLocker?.Close();
- _pidLocker = null;
-
- File.Delete(App.RunningAsViewer ? PidViewer : PidListener);
- }
- }
-}
\ No newline at end of file
diff --git a/QuickLook/PipeServerManager.cs b/QuickLook/PipeServerManager.cs
new file mode 100644
index 0000000..1c255d6
--- /dev/null
+++ b/QuickLook/PipeServerManager.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.IO.Pipes;
+using System.Threading.Tasks;
+
+namespace QuickLook
+{
+ internal class PipeServerManager : IDisposable
+ {
+ private const string PipeName = "QuickLook.App.Pipe";
+ private const string PipeCloseMessage = "QuickLook.App.Pipe.QuitSingal";
+ private static PipeServerManager _instance;
+
+ private NamedPipeServerStream _server;
+
+ public PipeServerManager()
+ {
+ _server = new NamedPipeServerStream(PipeName, PipeDirection.In);
+
+ new Task(() =>
+ {
+ using (var reader = new StreamReader(_server))
+ {
+ while (true)
+ {
+ Debug.WriteLine("PipeManager: WaitForConnection");
+
+ _server.WaitForConnection();
+ var msg = reader.ReadLine();
+
+ Debug.WriteLine($"PipeManager: {msg}");
+
+ if (msg == PipeCloseMessage)
+ return;
+
+ // dispatch message
+ MessageReceived?.Invoke(msg, new EventArgs());
+
+ _server.Disconnect();
+ }
+ }
+ }).Start();
+ }
+
+ public void Dispose()
+ {
+ GC.SuppressFinalize(this);
+
+ if (_server != null)
+ SendMessage(PipeCloseMessage);
+ _server?.Dispose();
+ _server = null;
+ }
+
+ public event EventHandler MessageReceived;
+
+ public static void SendMessage(string msg)
+ {
+ try
+ {
+ using (var client = new NamedPipeClientStream(".", PipeName, PipeDirection.Out))
+ {
+ client.Connect();
+
+ using (var writer = new StreamWriter(client))
+ {
+ writer.WriteLine(msg);
+ writer.Flush();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine(e.ToString());
+ }
+ }
+
+ ~PipeServerManager()
+ {
+ Dispose();
+ }
+
+ public static PipeServerManager GetInstance()
+ {
+ return _instance ?? (_instance = new PipeServerManager());
+ }
+ }
+}
\ No newline at end of file
diff --git a/QuickLook/QuickLook.csproj b/QuickLook/QuickLook.csproj
index 3662ed6..b2fa8c8 100644
--- a/QuickLook/QuickLook.csproj
+++ b/QuickLook/QuickLook.csproj
@@ -134,7 +134,7 @@
-
+