Allow in-place preview

e.g. QuickLook.exe C:\file.txt
This commit is contained in:
Paddy Xu
2017-05-13 00:08:55 +03:00
parent 5b2ecc2ef8
commit ac2bdcc9fc
9 changed files with 145 additions and 29 deletions

View File

@@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:QuickLook"
Startup="Application_Startup"
Exit="App_OnExit"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<ResourceDictionary>

View File

@@ -1,8 +1,8 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows;
namespace QuickLook
@@ -14,8 +14,7 @@ namespace QuickLook
{
public static readonly string AppFullPath = Assembly.GetExecutingAssembly().Location;
public static readonly string AppPath = Path.GetDirectoryName(AppFullPath);
private Mutex _isRunning;
public static bool RunningAsViewer;
protected override void OnStartup(StartupEventArgs e)
{
@@ -28,7 +27,46 @@ namespace QuickLook
private void Application_Startup(object sender, StartupEventArgs e)
{
EnsureSingleInstance();
if (e.Args.Any())
if (Directory.Exists(e.Args.First()) || File.Exists(e.Args.First()))
RunAsViewer(e);
else
RunAsListener(e);
else
RunAsListener(e);
}
private void RunAsViewer(StartupEventArgs e)
{
RunningAsViewer = true;
var runningPid = PidHelper.GetRunningInstance();
if (runningPid != -1)
{
Process.GetProcessById(runningPid).Kill();
Current.Shutdown();
return;
}
PidHelper.WritePid();
ViewWindowManager.GetInstance().InvokeViewer(e.Args.First());
}
private void RunAsListener(StartupEventArgs e)
{
RunningAsViewer = false;
if (PidHelper.GetRunningInstance() != -1)
{
MessageBox.Show("QuickLook is already running in the background.");
Current.Shutdown();
return;
}
PidHelper.WritePid();
TrayIcon.GetInstance();
if (!e.Args.Contains("/autorun"))
@@ -39,15 +77,12 @@ namespace QuickLook
BackgroundListener.GetInstance();
}
private void EnsureSingleInstance()
private void App_OnExit(object sender, ExitEventArgs e)
{
var isNew = false;
_isRunning = new Mutex(true, "QuickLook.App", out isNew);
if (!isNew)
{
MessageBox.Show("QuickLook is already running in the background.");
Current.Shutdown();
}
TrayIcon.GetInstance().Dispose();
BackgroundListener.GetInstance().Dispose();
PidHelper.DeletePid();
}
}
}

View File

@@ -1,8 +1,9 @@
using System.Windows.Forms;
using System;
using System.Windows.Forms;
namespace QuickLook
{
internal class BackgroundListener
internal class BackgroundListener : IDisposable
{
private static BackgroundListener _instance;
@@ -13,8 +14,16 @@ namespace QuickLook
InstallHook(HotkeyEventHandler);
}
public void Dispose()
{
_hook?.Dispose();
}
private void HotkeyEventHandler(object sender, KeyEventArgs e)
{
if (e.Modifiers != Keys.None)
return;
ViewWindowManager.GetInstance().InvokeRoutine();
}

View File

@@ -1,5 +1,5 @@
using System;
using System.IO;
using System.Diagnostics;
using System.Text;
using System.Windows.Interop;
using QuickLook.NativeMethods;
@@ -44,9 +44,11 @@ namespace QuickLook.Helpers
internal static bool IsFocusedWindowSelf()
{
var focusedWindowClass = GetWindowClassName(GetFocusedWindow());
var procId = Process.GetCurrentProcess().Id;
uint activeProcId;
User32.GetWindowThreadProcessId(GetFocusedWindow(), out activeProcId);
return focusedWindowClass.StartsWith($"HwndWrapper[{Path.GetFileName(App.AppFullPath)};;");
return activeProcId == procId;
}
internal static bool IsFocusedControlExplorerItem()

View File

@@ -27,7 +27,10 @@ namespace QuickLook.NativeMethods
internal static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
internal static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
internal static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr processId);
[DllImport("user32.dll")]
internal static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
[DllImport("user32.dll")]
internal static extern IntPtr AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, bool fAttach);

46
QuickLook/PidHelper.cs Normal file
View File

@@ -0,0 +1,46 @@
using System.Diagnostics;
using System.IO;
namespace QuickLook
{
internal static class PidHelper
{
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;
int.TryParse(File.ReadAllText(pid), out ppid);
try
{
Process.GetProcessById(ppid);
}
catch
{
return -1;
}
return ppid;
}
internal static void WritePid()
{
File.WriteAllText(App.RunningAsViewer ? PidViewer : PidListener, Process.GetCurrentProcess().Id.ToString());
}
internal static void DeletePid()
{
File.Delete(App.RunningAsViewer ? PidViewer : PidListener);
}
}
}

View File

@@ -87,6 +87,7 @@
<Compile Include="Controls\VisualTargetPresentationSource.cs" />
<Compile Include="ExtensionMethods\TypeExtensions.cs" />
<Compile Include="NativeMethods\ShellLink.cs" />
<Compile Include="PidHelper.cs" />
<Compile Include="PluginManager.cs" />
<Compile Include="Plugin\InfoPanel\DpiHelpers.cs" />
<Compile Include="Plugin\InfoPanel\Extensions.cs" />

View File

@@ -1,4 +1,5 @@
using System.Diagnostics;
using System;
using System.Diagnostics;
using System.Windows.Forms;
using QuickLook.Helpers;
using QuickLook.Properties;
@@ -6,7 +7,7 @@ using Application = System.Windows.Application;
namespace QuickLook
{
public class TrayIcon
public class TrayIcon : IDisposable
{
private static TrayIcon _instance;
@@ -39,6 +40,11 @@ namespace QuickLook
_icon.ContextMenu.Popup += (sender, e) => { _itemAutorun.Checked = AutoStartupHelper.IsAutorun(); };
}
public void Dispose()
{
_icon.Visible = false;
}
public void ShowNotification(string title, string content, bool isError = false)
{
_icon.ShowBalloonTip(5000, title, content, isError ? ToolTipIcon.Error : ToolTipIcon.Info);

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using QuickLook.ExtensionMethods;
using QuickLook.Helpers;
using QuickLook.Plugin;
@@ -16,16 +17,8 @@ namespace QuickLook
private MainWindow _viewWindow;
internal void InvokeRoutine()
internal void InvokeViewer(string path)
{
if (!WindowHelper.IsFocusedControlExplorerItem())
if (!WindowHelper.IsFocusedWindowSelf())
return;
if (CloseCurrentWindow())
return;
var path = GetCurrentSelection();
if (string.IsNullOrEmpty(path))
return;
if (!Directory.Exists(path) && !File.Exists(path))
@@ -36,11 +29,31 @@ namespace QuickLook
BeginShowNewWindow(matchedPlugin, path);
}
internal void InvokeRoutine()
{
if (!WindowHelper.IsFocusedControlExplorerItem())
if (!WindowHelper.IsFocusedWindowSelf())
return;
if (CloseCurrentWindow())
return;
var path = GetCurrentSelection();
InvokeViewer(path);
}
private void BeginShowNewWindow(IViewer matchedPlugin, string path)
{
_viewWindow = new MainWindow();
_viewWindow.Closed += (sender2, e2) =>
{
if (App.RunningAsViewer)
{
Application.Current.Shutdown();
return;
}
_viewWindow.Dispose();
_viewWindow = null;
GC.Collect();