mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-14 03:29:07 +00:00
real async plugin loading
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace QuickLook
|
namespace QuickLook
|
||||||
{
|
{
|
||||||
@@ -25,7 +26,8 @@ namespace QuickLook
|
|||||||
if (e.Modifiers != Keys.None)
|
if (e.Modifiers != Keys.None)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ViewWindowManager.GetInstance().InvokeRoutine(e);
|
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => ViewWindowManager.GetInstance().InvokeRoutine(e)),
|
||||||
|
DispatcherPriority.ApplicationIdle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InstallKeyHook(KeyEventHandler handler)
|
private void InstallKeyHook(KeyEventHandler handler)
|
||||||
|
@@ -16,9 +16,6 @@ namespace QuickLook
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MainWindowTransparent : Window
|
public partial class MainWindowTransparent : Window
|
||||||
{
|
{
|
||||||
private string _path = string.Empty;
|
|
||||||
private IViewer _plugin;
|
|
||||||
|
|
||||||
internal MainWindowTransparent()
|
internal MainWindowTransparent()
|
||||||
{
|
{
|
||||||
// this object should be initialized before loading UI components, because many of which are binding to it.
|
// this object should be initialized before loading UI components, because many of which are binding to it.
|
||||||
@@ -43,18 +40,21 @@ namespace QuickLook
|
|||||||
ViewWindowManager.GetInstance().RunAndClosePreview();
|
ViewWindowManager.GetInstance().RunAndClosePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string PreviewPath { get; private set; }
|
||||||
|
public IViewer Plugin { get; private set; }
|
||||||
|
|
||||||
public ContextObject ContextObject { get; private set; }
|
public ContextObject ContextObject { get; private set; }
|
||||||
|
|
||||||
internal void RunAndHide()
|
internal void RunAndHide()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_path))
|
if (string.IsNullOrEmpty(PreviewPath))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Process.Start(new ProcessStartInfo(_path)
|
Process.Start(new ProcessStartInfo(PreviewPath)
|
||||||
{
|
{
|
||||||
WorkingDirectory = Path.GetDirectoryName(_path)
|
WorkingDirectory = Path.GetDirectoryName(PreviewPath)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -96,21 +96,21 @@ namespace QuickLook
|
|||||||
|
|
||||||
ContextObject.Reset();
|
ContextObject.Reset();
|
||||||
|
|
||||||
_plugin?.Cleanup();
|
Plugin?.Cleanup();
|
||||||
_plugin = null;
|
Plugin = null;
|
||||||
|
|
||||||
ProcessHelper.PerformAggressiveGC();
|
ProcessHelper.PerformAggressiveGC();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void BeginShow(IViewer matchedPlugin, string path)
|
internal void BeginShow(IViewer matchedPlugin, string path, Action<ExceptionDispatchInfo> exceptionHandler)
|
||||||
{
|
{
|
||||||
_path = path;
|
PreviewPath = path;
|
||||||
_plugin = matchedPlugin;
|
Plugin = matchedPlugin;
|
||||||
|
|
||||||
ContextObject.ViewerWindow = this;
|
ContextObject.ViewerWindow = this;
|
||||||
|
|
||||||
// get window size before showing it
|
// get window size before showing it
|
||||||
_plugin.Prepare(path, ContextObject);
|
Plugin.Prepare(path, ContextObject);
|
||||||
|
|
||||||
SetOpenWithButtonAndPath();
|
SetOpenWithButtonAndPath();
|
||||||
|
|
||||||
@@ -129,31 +129,27 @@ namespace QuickLook
|
|||||||
//WindowHelper.SetActivate(new WindowInteropHelper(this), ContextObject.CanFocus);
|
//WindowHelper.SetActivate(new WindowInteropHelper(this), ContextObject.CanFocus);
|
||||||
|
|
||||||
// load plugin, do not block UI
|
// load plugin, do not block UI
|
||||||
Exception thrown = null;
|
|
||||||
Dispatcher.BeginInvoke(new Action(() =>
|
Dispatcher.BeginInvoke(new Action(() =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_plugin.View(path, ContextObject);
|
Plugin.View(path, ContextObject);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
thrown = e;
|
exceptionHandler(ExceptionDispatchInfo.Capture(e));
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
DispatcherPriority.Render).Wait();
|
DispatcherPriority.Input);
|
||||||
|
|
||||||
if (thrown != null)
|
|
||||||
ExceptionDispatchInfo.Capture(thrown).Throw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetOpenWithButtonAndPath()
|
private void SetOpenWithButtonAndPath()
|
||||||
{
|
{
|
||||||
var isExe = FileHelper.GetAssocApplication(_path, out string appFriendlyName);
|
var isExe = FileHelper.GetAssocApplication(PreviewPath, out string appFriendlyName);
|
||||||
|
|
||||||
buttonOpenWith.Content = isExe == null
|
buttonOpenWith.Content = isExe == null
|
||||||
? Directory.Exists(_path)
|
? Directory.Exists(PreviewPath)
|
||||||
? $"Browse “{Path.GetFileName(_path)}”"
|
? $"Browse “{Path.GetFileName(PreviewPath)}”"
|
||||||
: "Open..."
|
: "Open..."
|
||||||
: isExe == true
|
: isExe == true
|
||||||
? $"Run “{appFriendlyName}”"
|
? $"Run “{appFriendlyName}”"
|
||||||
|
@@ -4,7 +4,6 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using QuickLook.ExtensionMethods;
|
using QuickLook.ExtensionMethods;
|
||||||
using QuickLook.Plugin;
|
using QuickLook.Plugin;
|
||||||
using QuickLook.Plugin.InfoPanel;
|
using QuickLook.Plugin.InfoPanel;
|
||||||
|
@@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Runtime.ExceptionServices;
|
using System.Runtime.ExceptionServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using System.Windows.Threading;
|
||||||
using QuickLook.Helpers;
|
using QuickLook.Helpers;
|
||||||
using QuickLook.Plugin;
|
using QuickLook.Plugin;
|
||||||
|
|
||||||
@@ -123,8 +124,8 @@ namespace QuickLook
|
|||||||
|
|
||||||
private void SwitchPreviewRemoteInvoke(HeartbeatEventArgs e)
|
private void SwitchPreviewRemoteInvoke(HeartbeatEventArgs e)
|
||||||
{
|
{
|
||||||
// sleep for 1.5s
|
// sleep for 0.6s
|
||||||
if (e.InvokeTick - _lastSwitchTick < 1.5 * TimeSpan.TicksPerSecond)
|
if (e.InvokeTick - _lastSwitchTick < 0.6 * TimeSpan.TicksPerSecond)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (e.FocusedFile == _path)
|
if (e.FocusedFile == _path)
|
||||||
@@ -135,7 +136,7 @@ namespace QuickLook
|
|||||||
if (string.IsNullOrEmpty(e.FocusedFile))
|
if (string.IsNullOrEmpty(e.FocusedFile))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_currentMainWindow?.Dispatcher.Invoke(() => SwitchPreview());
|
_currentMainWindow?.Dispatcher.BeginInvoke(new Action(SwitchPreview), DispatcherPriority.ApplicationIdle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RunFocusMonitor()
|
private void RunFocusMonitor()
|
||||||
@@ -158,26 +159,24 @@ namespace QuickLook
|
|||||||
|
|
||||||
internal bool InvokeViewer(string path = null)
|
internal bool InvokeViewer(string path = null)
|
||||||
{
|
{
|
||||||
if (path == null)
|
if (path != null)
|
||||||
path = _path;
|
_path = path;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(_path))
|
||||||
return false;
|
return false;
|
||||||
if (!Directory.Exists(path) && !File.Exists(path))
|
if (!Directory.Exists(_path) && !File.Exists(_path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RunFocusMonitor();
|
RunFocusMonitor();
|
||||||
|
|
||||||
var matchedPlugin = PluginManager.GetInstance().FindMatch(path);
|
var matchedPlugin = PluginManager.GetInstance().FindMatch(_path);
|
||||||
|
|
||||||
BeginShowNewWindow(matchedPlugin, path);
|
BeginShowNewWindow(matchedPlugin);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BeginShowNewWindow(IViewer matchedPlugin, string path)
|
private void BeginShowNewWindow(IViewer matchedPlugin)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
_currentMainWindow.UnloadPlugin();
|
_currentMainWindow.UnloadPlugin();
|
||||||
|
|
||||||
@@ -189,28 +188,24 @@ namespace QuickLook
|
|||||||
if (!ReferenceEquals(oldWindow, _currentMainWindow))
|
if (!ReferenceEquals(oldWindow, _currentMainWindow))
|
||||||
oldWindow.BeginHide();
|
oldWindow.BeginHide();
|
||||||
|
|
||||||
_currentMainWindow.BeginShow(matchedPlugin, path);
|
_currentMainWindow.BeginShow(matchedPlugin, _path, CurrentPluginFailed);
|
||||||
}
|
}
|
||||||
catch (Exception e) // if current plugin failed, switch to default one.
|
|
||||||
|
private void CurrentPluginFailed(ExceptionDispatchInfo e)
|
||||||
{
|
{
|
||||||
|
var plugin = _currentMainWindow.Plugin.GetType();
|
||||||
|
|
||||||
_currentMainWindow.BeginHide();
|
_currentMainWindow.BeginHide();
|
||||||
|
|
||||||
TrayIconManager.GetInstance().ShowNotification("", $"Failed to preview {Path.GetFileName(path)}", true);
|
TrayIconManager.GetInstance().ShowNotification("", $"Failed to preview {Path.GetFileName(_path)}", true);
|
||||||
|
|
||||||
Debug.WriteLine(e.ToString());
|
Debug.WriteLine(e.ToString());
|
||||||
Debug.WriteLine(e.StackTrace);
|
Debug.WriteLine(e.SourceException.StackTrace);
|
||||||
|
|
||||||
if (matchedPlugin != PluginManager.GetInstance().DefaultPlugin)
|
if (plugin != PluginManager.GetInstance().DefaultPlugin.GetType())
|
||||||
{
|
BeginShowNewWindow(PluginManager.GetInstance().DefaultPlugin);
|
||||||
matchedPlugin.Cleanup();
|
|
||||||
matchedPlugin = PluginManager.GetInstance().DefaultPlugin;
|
|
||||||
BeginShowNewWindow(matchedPlugin, path);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
e.Throw();
|
||||||
ExceptionDispatchInfo.Capture(e).Throw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ViewWindowManager GetInstance()
|
internal static ViewWindowManager GetInstance()
|
||||||
|
Reference in New Issue
Block a user