mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-13 19:19:10 +00:00
add "Open with" button
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||||
<Product Id="*" Name="QuickLook" Language="1033"
|
<Product Id="*" Name="QuickLook" Language="1033"
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Interop;
|
|
||||||
|
|
||||||
namespace QuickLook.Plugin.IPreviewHandlers
|
namespace QuickLook.Plugin.IPreviewHandlers
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace QuickLook.Plugin.PDFViewer
|
namespace QuickLook.Plugin.PDFViewer
|
||||||
{
|
{
|
||||||
|
@@ -24,7 +24,7 @@ namespace QuickLook
|
|||||||
if (e.Modifiers != Keys.None)
|
if (e.Modifiers != Keys.None)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ViewWindowManager.GetInstance().InvokeRoutine(e.KeyCode != Keys.Space);
|
ViewWindowManager.GetInstance().InvokeRoutine(e.KeyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InstallHook(KeyEventHandler handler)
|
private void InstallHook(KeyEventHandler handler)
|
||||||
@@ -32,6 +32,8 @@ namespace QuickLook
|
|||||||
_hook = GlobalKeyboardHook.GetInstance();
|
_hook = GlobalKeyboardHook.GetInstance();
|
||||||
|
|
||||||
_hook.HookedKeys.Add(Keys.Space);
|
_hook.HookedKeys.Add(Keys.Space);
|
||||||
|
//_hook.HookedKeys.Add(Keys.Enter);
|
||||||
|
|
||||||
_hook.HookedKeys.Add(Keys.Up);
|
_hook.HookedKeys.Add(Keys.Up);
|
||||||
_hook.HookedKeys.Add(Keys.Down);
|
_hook.HookedKeys.Add(Keys.Down);
|
||||||
_hook.HookedKeys.Add(Keys.Left);
|
_hook.HookedKeys.Add(Keys.Left);
|
||||||
|
134
QuickLook/Helpers/FileHelper.cs
Normal file
134
QuickLook/Helpers/FileHelper.cs
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using QuickLook.NativeMethods;
|
||||||
|
|
||||||
|
namespace QuickLook.Helpers
|
||||||
|
{
|
||||||
|
internal class FileHelper
|
||||||
|
{
|
||||||
|
private static string GetExecutable(string line)
|
||||||
|
{
|
||||||
|
var ret = line.StartsWith("\"")
|
||||||
|
? line.Split(new[] {"\" "}, 2, StringSplitOptions.None)
|
||||||
|
: line.Split(new[] {' '}, 2, StringSplitOptions.None);
|
||||||
|
|
||||||
|
ret[0] = ret[0].StartsWith("\"") ? ret[0].Substring(1) : ret[0];
|
||||||
|
return ret[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool? GetAssocApplication(string path, out string executePath, out string appFriendlyName)
|
||||||
|
{
|
||||||
|
executePath = string.Empty;
|
||||||
|
appFriendlyName = string.Empty;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (Directory.Exists(path))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!File.Exists(path))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (Path.GetExtension(path) == ".lnk")
|
||||||
|
{
|
||||||
|
var shell = (IWshShell) new WshShell();
|
||||||
|
var link = shell.CreateShortcut(path);
|
||||||
|
path = GetExecutable(link.TargetPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ext = Path.GetExtension(path).ToLower();
|
||||||
|
var isExe = ext.ToLower() == ".exe";
|
||||||
|
|
||||||
|
// no assoc. app. found
|
||||||
|
if (string.IsNullOrEmpty(GetAssocApplicationNative(ext, AssocStr.Command)))
|
||||||
|
if (string.IsNullOrEmpty(GetAssocApplicationNative(ext, AssocStr.AppId))) // UWP
|
||||||
|
return null;
|
||||||
|
|
||||||
|
executePath = path;
|
||||||
|
appFriendlyName = isExe
|
||||||
|
? FileVersionInfo.GetVersionInfo(path).FileDescription
|
||||||
|
: GetAssocApplicationNative(ext, AssocStr.FriendlyAppName);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(appFriendlyName))
|
||||||
|
appFriendlyName = Path.GetFileName(path);
|
||||||
|
|
||||||
|
return isExe;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
private static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra,
|
||||||
|
[Out] StringBuilder sOut, [In] [Out] ref uint nOut);
|
||||||
|
|
||||||
|
private static string GetAssocApplicationNative(string fileExtensionIncludingDot, AssocStr str)
|
||||||
|
{
|
||||||
|
uint cOut = 0;
|
||||||
|
if (AssocQueryString(AssocF.Verify | AssocF.RemapRunDll | AssocF.InitIgnoreUnknown, str,
|
||||||
|
fileExtensionIncludingDot, null, null,
|
||||||
|
ref cOut) != 1)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var pOut = new StringBuilder((int) cOut);
|
||||||
|
if (AssocQueryString(AssocF.Verify | AssocF.RemapRunDll | AssocF.InitIgnoreUnknown, str,
|
||||||
|
fileExtensionIncludingDot, null, pOut,
|
||||||
|
ref cOut) != 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return pOut.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
[Flags]
|
||||||
|
private enum AssocF
|
||||||
|
{
|
||||||
|
InitNoRemapCLSID = 0x1,
|
||||||
|
InitByExeName = 0x2,
|
||||||
|
OpenByExeName = 0x2,
|
||||||
|
InitDefaultToStar = 0x4,
|
||||||
|
InitDefaultToFolder = 0x8,
|
||||||
|
NoUserSettings = 0x10,
|
||||||
|
NoTruncate = 0x20,
|
||||||
|
Verify = 0x40,
|
||||||
|
RemapRunDll = 0x80,
|
||||||
|
NoFixUps = 0x100,
|
||||||
|
IgnoreBaseClass = 0x200,
|
||||||
|
InitIgnoreUnknown = 0x400,
|
||||||
|
InitFixedProgid = 0x800,
|
||||||
|
IsProtocol = 0x1000,
|
||||||
|
InitForFile = 0x2000
|
||||||
|
}
|
||||||
|
|
||||||
|
//[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
private enum AssocStr
|
||||||
|
{
|
||||||
|
Command = 1,
|
||||||
|
Executable,
|
||||||
|
FriendlyDocName,
|
||||||
|
FriendlyAppName,
|
||||||
|
NoOpen,
|
||||||
|
ShellNewValue,
|
||||||
|
DdeCommand,
|
||||||
|
DdeIfExec,
|
||||||
|
DdeApplication,
|
||||||
|
DdeTopic,
|
||||||
|
InfoTip,
|
||||||
|
QuickTip,
|
||||||
|
TileInfo,
|
||||||
|
ContentType,
|
||||||
|
DefaultIcon,
|
||||||
|
ShellExtension,
|
||||||
|
DropTarget,
|
||||||
|
DelegateExecute,
|
||||||
|
SupportedUriProtocols,
|
||||||
|
ProgId,
|
||||||
|
AppId,
|
||||||
|
AppPublisher,
|
||||||
|
AppIconReference,
|
||||||
|
Max
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -57,6 +57,11 @@
|
|||||||
WindowChrome.IsHitTestVisibleInChrome="True"
|
WindowChrome.IsHitTestVisibleInChrome="True"
|
||||||
Height="15" Margin="10,0" Foreground="Gray"
|
Height="15" Margin="10,0" Foreground="Gray"
|
||||||
Cursor="Hand" />
|
Cursor="Hand" />
|
||||||
|
<Button x:Name="buttonOpenWith" DockPanel.Dock="Right" Content="Open with ..." Height="20"
|
||||||
|
Margin="10,0,0,0" Padding="5,0"
|
||||||
|
Focusable="False" Cursor="Hand"
|
||||||
|
Background="#E5EEEEEE" BorderBrush="#E59A9A9A"
|
||||||
|
WindowChrome.IsHitTestVisibleInChrome="True" Foreground="#FF404040" />
|
||||||
<!-- set grid.background colour makes it clickable -->
|
<!-- set grid.background colour makes it clickable -->
|
||||||
<Grid x:Name="titleArea" Background="Transparent">
|
<Grid x:Name="titleArea" Background="Transparent">
|
||||||
<TextBlock Text="{Binding ContextObject.Title, ElementName=mainWindow}" FontSize="14"
|
<TextBlock Text="{Binding ContextObject.Title, ElementName=mainWindow}" FontSize="14"
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using QuickLook.Helpers;
|
using QuickLook.Helpers;
|
||||||
@@ -13,6 +14,8 @@ namespace QuickLook
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MainWindowTransparent : Window
|
public partial class MainWindowTransparent : Window
|
||||||
{
|
{
|
||||||
|
private string _path = string.Empty;
|
||||||
|
|
||||||
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.
|
||||||
@@ -31,10 +34,27 @@ namespace QuickLook
|
|||||||
};
|
};
|
||||||
|
|
||||||
buttonCloseWindow.MouseLeftButtonUp += (sender, e) => BeginHide(true);
|
buttonCloseWindow.MouseLeftButtonUp += (sender, e) => BeginHide(true);
|
||||||
|
|
||||||
|
/*PreviewKeyUp += (sender, e) =>
|
||||||
|
{
|
||||||
|
if (e.Key == Key.Enter)
|
||||||
|
OpenWithAssocApp();
|
||||||
|
};*/
|
||||||
|
|
||||||
|
buttonOpenWith.Click += (sender, e) => OpenWithAssocApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContextObject ContextObject { get; private set; }
|
public ContextObject ContextObject { get; private set; }
|
||||||
|
|
||||||
|
private void OpenWithAssocApp()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Process.Start(new ProcessStartInfo(_path) {WorkingDirectory = Path.GetDirectoryName(_path)});
|
||||||
|
BeginHide(true);
|
||||||
|
}
|
||||||
|
|
||||||
private new void Show()
|
private new void Show()
|
||||||
{
|
{
|
||||||
// revert UI changes
|
// revert UI changes
|
||||||
@@ -107,6 +127,8 @@ namespace QuickLook
|
|||||||
// get window size before showing it
|
// get window size before showing it
|
||||||
ContextObject.ViewerPlugin.Prepare(path, ContextObject);
|
ContextObject.ViewerPlugin.Prepare(path, ContextObject);
|
||||||
|
|
||||||
|
SetOpenWithButtonAndPath(path);
|
||||||
|
|
||||||
Show();
|
Show();
|
||||||
|
|
||||||
// load plugin, do not block UI
|
// load plugin, do not block UI
|
||||||
@@ -128,6 +150,15 @@ namespace QuickLook
|
|||||||
throw thrown;
|
throw thrown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetOpenWithButtonAndPath(string path)
|
||||||
|
{
|
||||||
|
var isExe = FileHelper.GetAssocApplication(path, out string executePath, out string appFriendlyName);
|
||||||
|
|
||||||
|
_path = executePath;
|
||||||
|
buttonOpenWith.Visibility = isExe == null ? Visibility.Collapsed : Visibility.Visible;
|
||||||
|
buttonOpenWith.Content = isExe == true ? $"Run {appFriendlyName}" : $"Open with {appFriendlyName}";
|
||||||
|
}
|
||||||
|
|
||||||
internal bool BeginHide(bool quit = false)
|
internal bool BeginHide(bool quit = false)
|
||||||
{
|
{
|
||||||
if (quit && App.RunningAsViewer)
|
if (quit && App.RunningAsViewer)
|
||||||
|
@@ -42,4 +42,36 @@ namespace QuickLook.NativeMethods
|
|||||||
void Resolve(IntPtr hwnd, int fFlags);
|
void Resolve(IntPtr hwnd, int fFlags);
|
||||||
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
|
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8")]
|
||||||
|
internal class WshShell
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||||
|
[Guid("F935DC21-1CF0-11D0-ADB9-00C04FD58A0B")]
|
||||||
|
internal interface IWshShell
|
||||||
|
{
|
||||||
|
IWshShortcut CreateShortcut(string pathLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||||
|
[Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")]
|
||||||
|
internal interface IWshShortcut
|
||||||
|
{
|
||||||
|
string FullName { get; }
|
||||||
|
string Arguments { get; set; }
|
||||||
|
string Description { get; set; }
|
||||||
|
string Hotkey { get; set; }
|
||||||
|
string IconLocation { get; set; }
|
||||||
|
string RelativePath { set; }
|
||||||
|
string TargetPath { get; set; }
|
||||||
|
int WindowStyle { get; set; }
|
||||||
|
string WorkingDirectory { get; set; }
|
||||||
|
void Load([In] string pathLink);
|
||||||
|
void Save();
|
||||||
|
}
|
||||||
}
|
}
|
@@ -105,6 +105,7 @@
|
|||||||
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\Windows81WindowBlurController.cs" />
|
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\Windows81WindowBlurController.cs" />
|
||||||
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\Windows8WindowBlurController.cs" />
|
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\Windows8WindowBlurController.cs" />
|
||||||
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\WindowsVistaWindowBlurController.cs" />
|
<Compile Include="Helpers\BlurLibrary\PlatformsImpl\WindowsVistaWindowBlurController.cs" />
|
||||||
|
<Compile Include="Helpers\FileHelper.cs" />
|
||||||
<Compile Include="MainWindowNoTransparent.cs" />
|
<Compile Include="MainWindowNoTransparent.cs" />
|
||||||
<Compile Include="NativeMethods\ShellLink.cs" />
|
<Compile Include="NativeMethods\ShellLink.cs" />
|
||||||
<Compile Include="PidHelper.cs" />
|
<Compile Include="PidHelper.cs" />
|
||||||
@@ -118,7 +119,7 @@
|
|||||||
<Compile Include="Plugin\InfoPanel\PluginInterface.cs" />
|
<Compile Include="Plugin\InfoPanel\PluginInterface.cs" />
|
||||||
<Compile Include="Plugin\InfoPanel\WindowsThumbnailProvider.cs" />
|
<Compile Include="Plugin\InfoPanel\WindowsThumbnailProvider.cs" />
|
||||||
<Compile Include="Plugin\IViewer.cs" />
|
<Compile Include="Plugin\IViewer.cs" />
|
||||||
<Compile Include="Helpers\DpiHelpers.cs" />
|
<Compile Include="Helpers\DpiHelper.cs" />
|
||||||
<Compile Include="TrayIconManager.cs" />
|
<Compile Include="TrayIconManager.cs" />
|
||||||
<Compile Include="Plugin\ContextObject.cs" />
|
<Compile Include="Plugin\ContextObject.cs" />
|
||||||
<Compile Include="Helpers\WindowHelper.cs" />
|
<Compile Include="Helpers\WindowHelper.cs" />
|
||||||
|
@@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Forms;
|
||||||
using QuickLook.Helpers;
|
using QuickLook.Helpers;
|
||||||
using QuickLook.Plugin;
|
using QuickLook.Plugin;
|
||||||
|
|
||||||
@@ -26,8 +27,11 @@ namespace QuickLook
|
|||||||
_currentMainWindow = _viewWindowTransparentTransparent;
|
_currentMainWindow = _viewWindowTransparentTransparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InvokeRoutine(bool replaceView = false)
|
internal void InvokeRoutine(Keys key)
|
||||||
{
|
{
|
||||||
|
// do we need switch to another file?
|
||||||
|
var replaceView = key == Keys.Up || key == Keys.Down || key == Keys.Left || key == Keys.Right;
|
||||||
|
|
||||||
if (replaceView && _currentMainWindow.IsLoaded && _currentMainWindow.Visibility != Visibility.Visible)
|
if (replaceView && _currentMainWindow.IsLoaded && _currentMainWindow.Visibility != Visibility.Visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user