mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-12-24 02:00:55 +08:00
Allow in-place preview
e.g. QuickLook.exe C:\file.txt
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
46
QuickLook/PidHelper.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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" />
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user