mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 19:57:57 +01:00
This is a PoC. It adds the ability to peek a file using a named pipe and a command line. Usage/testing before this gets merged and released: 1. Build release configuration of Peek.UI and Peek.CLI. 2. Terminate PowerToys.Peek.UI.exe if running. 3. Back up and replace PowerToys.Peek.UI[.dll;.exe;.pdb;.pri]. Use [Everything](https://www.voidtools.com/downloads/) to find the source and destination folders. 4. Call `PowerToys.Peek.CLI.exe <path>` or send the path to peek to the `PeekPipe` named pipe. If this solution is OK, documentation and installer need to be updated and a follow-up issue needs to be filed to support navigation. --------- Co-authored-by: Clint Rutkas <clint@rutkas.com> Co-authored-by: Leilei Zhang <leilzh@microsoft.com> Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
20b5ca79a3
commit
31a0deee35
@@ -62,6 +62,12 @@ namespace Peek.UI
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IFileSystemItem? _currentItem;
|
private IFileSystemItem? _currentItem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Work around missing navigation when peeking from CLI.
|
||||||
|
/// TODO: Implement navigation when peeking from CLI.
|
||||||
|
/// </summary>
|
||||||
|
private bool _isFromCli;
|
||||||
|
|
||||||
partial void OnCurrentItemChanged(IFileSystemItem? value)
|
partial void OnCurrentItemChanged(IFileSystemItem? value)
|
||||||
{
|
{
|
||||||
WindowTitle = value != null
|
WindowTitle = value != null
|
||||||
@@ -129,7 +135,24 @@ namespace Peek.UI
|
|||||||
NavigationThrottleTimer.Interval = TimeSpan.FromMilliseconds(NavigationThrottleDelayMs);
|
NavigationThrottleTimer.Interval = TimeSpan.FromMilliseconds(NavigationThrottleDelayMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(HWND foregroundWindowHandle)
|
public void Initialize(SelectedItem selectedItem)
|
||||||
|
{
|
||||||
|
switch (selectedItem)
|
||||||
|
{
|
||||||
|
case SelectedItemByPath selectedItemByPath:
|
||||||
|
InitializeFromCli(selectedItemByPath.Path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SelectedItemByWindowHandle selectedItemByWindowHandle:
|
||||||
|
InitializeFromExplorer(selectedItemByWindowHandle.WindowHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException($"Invalid type of selected item: '{selectedItem.GetType().FullName}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeFromExplorer(HWND foregroundWindowHandle)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -141,10 +164,20 @@ namespace Peek.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
_currentIndex = DisplayIndex = 0;
|
_currentIndex = DisplayIndex = 0;
|
||||||
|
_isFromCli = false;
|
||||||
|
|
||||||
CurrentItem = (Items != null && Items.Count > 0) ? Items[0] : null;
|
CurrentItem = (Items != null && Items.Count > 0) ? Items[0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitializeFromCli(string path)
|
||||||
|
{
|
||||||
|
// TODO: implement navigation
|
||||||
|
_isFromCli = true;
|
||||||
|
Items = null;
|
||||||
|
_currentIndex = DisplayIndex = 0;
|
||||||
|
CurrentItem = new FileItem(path, Path.GetFileName(path));
|
||||||
|
}
|
||||||
|
|
||||||
public void Uninitialize()
|
public void Uninitialize()
|
||||||
{
|
{
|
||||||
_currentIndex = DisplayIndex = 0;
|
_currentIndex = DisplayIndex = 0;
|
||||||
@@ -153,6 +186,7 @@ namespace Peek.UI
|
|||||||
Items = null;
|
Items = null;
|
||||||
_navigationDirection = NavigationDirection.Forwards;
|
_navigationDirection = NavigationDirection.Forwards;
|
||||||
IsErrorVisible = false;
|
IsErrorVisible = false;
|
||||||
|
_isFromCli = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AttemptPreviousNavigation() => Navigate(NavigationDirection.Backwards);
|
public void AttemptPreviousNavigation() => Navigate(NavigationDirection.Backwards);
|
||||||
@@ -166,6 +200,12 @@ namespace Peek.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: implement navigation.
|
||||||
|
if (_isFromCli)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Items == null || Items.Count == _deletedItemIndexes.Count)
|
if (Items == null || Items.Count == _deletedItemIndexes.Count)
|
||||||
{
|
{
|
||||||
_currentIndex = DisplayIndex = 0;
|
_currentIndex = DisplayIndex = 0;
|
||||||
|
|||||||
11
src/modules/peek/Peek.UI/Models/SelectedItem.cs
Normal file
11
src/modules/peek/Peek.UI/Models/SelectedItem.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
namespace Peek.UI.Models
|
||||||
|
{
|
||||||
|
public abstract class SelectedItem
|
||||||
|
{
|
||||||
|
public abstract bool Matches(string? path);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/modules/peek/Peek.UI/Models/SelectedItemByPath.cs
Normal file
23
src/modules/peek/Peek.UI/Models/SelectedItemByPath.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Peek.UI.Models
|
||||||
|
{
|
||||||
|
public class SelectedItemByPath : SelectedItem
|
||||||
|
{
|
||||||
|
public string Path { get; }
|
||||||
|
|
||||||
|
public SelectedItemByPath(string path)
|
||||||
|
{
|
||||||
|
Path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Matches(string? path)
|
||||||
|
{
|
||||||
|
return string.Equals(Path, path, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Peek.UI.Extensions;
|
||||||
|
using Peek.UI.Helpers;
|
||||||
|
using Windows.Win32.Foundation;
|
||||||
|
|
||||||
|
namespace Peek.UI.Models
|
||||||
|
{
|
||||||
|
public class SelectedItemByWindowHandle : SelectedItem
|
||||||
|
{
|
||||||
|
public HWND WindowHandle { get; }
|
||||||
|
|
||||||
|
public SelectedItemByWindowHandle(HWND windowHandle)
|
||||||
|
{
|
||||||
|
WindowHandle = windowHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Matches(string? path)
|
||||||
|
{
|
||||||
|
var selectedItems = FileExplorerHelper.GetSelectedItems(WindowHandle);
|
||||||
|
var selectedItemsCount = selectedItems?.GetCount() ?? 0;
|
||||||
|
if (selectedItems == null || selectedItemsCount == 0 || selectedItemsCount > 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileExplorerSelectedItemPath = selectedItems.GetItemAt(0).ToIFileSystemItem().Path;
|
||||||
|
var currentItemPath = path;
|
||||||
|
return fileExplorerSelectedItemPath != null && currentItemPath != null && fileExplorerSelectedItemPath != currentItemPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,16 +3,19 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using ManagedCommon;
|
using ManagedCommon;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.PowerToys.Telemetry;
|
using Microsoft.PowerToys.Telemetry;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
using Peek.Common;
|
using Peek.Common;
|
||||||
using Peek.FilePreviewer;
|
using Peek.FilePreviewer;
|
||||||
using Peek.FilePreviewer.Models;
|
using Peek.FilePreviewer.Models;
|
||||||
using Peek.FilePreviewer.Previewers;
|
using Peek.FilePreviewer.Previewers;
|
||||||
|
using Peek.UI.Models;
|
||||||
using Peek.UI.Native;
|
using Peek.UI.Native;
|
||||||
using Peek.UI.Telemetry.Events;
|
using Peek.UI.Telemetry.Events;
|
||||||
using Peek.UI.Views;
|
using Peek.UI.Views;
|
||||||
@@ -23,7 +26,7 @@ namespace Peek.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides application-specific behavior to supplement the default Application class.
|
/// Provides application-specific behavior to supplement the default Application class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class App : Application, IApp
|
public partial class App : Application, IApp, IDisposable
|
||||||
{
|
{
|
||||||
public static int PowerToysPID { get; set; }
|
public static int PowerToysPID { get; set; }
|
||||||
|
|
||||||
@@ -36,6 +39,10 @@ namespace Peek.UI
|
|||||||
|
|
||||||
private MainWindow? Window { get; set; }
|
private MainWindow? Window { get; set; }
|
||||||
|
|
||||||
|
private bool _disposed;
|
||||||
|
private SelectedItem? _selectedItem;
|
||||||
|
private bool _launchedFromCli;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="App"/> class.
|
/// Initializes a new instance of the <see cref="App"/> class.
|
||||||
/// Initializes the singleton application object. This is the first line of authored code
|
/// Initializes the singleton application object. This is the first line of authored code
|
||||||
@@ -52,22 +59,22 @@ namespace Peek.UI
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Logger.InitializeLogger("\\Peek\\Logs");
|
Logger.InitializeLogger("\\Peek\\Logs");
|
||||||
|
|
||||||
Host = Microsoft.Extensions.Hosting.Host.
|
Host = Microsoft.Extensions.Hosting.Host
|
||||||
CreateDefaultBuilder().
|
.CreateDefaultBuilder()
|
||||||
UseContentRoot(AppContext.BaseDirectory).
|
.UseContentRoot(AppContext.BaseDirectory)
|
||||||
ConfigureServices((context, services) =>
|
.ConfigureServices((context, services) =>
|
||||||
{
|
{
|
||||||
// Core Services
|
// Core Services
|
||||||
services.AddTransient<NeighboringItemsQuery>();
|
services.AddTransient<NeighboringItemsQuery>();
|
||||||
services.AddSingleton<IUserSettings, UserSettings>();
|
services.AddSingleton<IUserSettings, UserSettings>();
|
||||||
services.AddSingleton<IPreviewSettings, PreviewSettings>();
|
services.AddSingleton<IPreviewSettings, PreviewSettings>();
|
||||||
|
|
||||||
// Views and ViewModels
|
// Views and ViewModels
|
||||||
services.AddTransient<TitleBar>();
|
services.AddTransient<TitleBar>();
|
||||||
services.AddTransient<FilePreview>();
|
services.AddTransient<FilePreview>();
|
||||||
services.AddTransient<MainWindowViewModel>();
|
services.AddTransient<MainWindowViewModel>();
|
||||||
}).
|
})
|
||||||
Build();
|
.Build();
|
||||||
|
|
||||||
UnhandledException += App_UnhandledException;
|
UnhandledException += App_UnhandledException;
|
||||||
}
|
}
|
||||||
@@ -99,6 +106,7 @@ namespace Peek.UI
|
|||||||
var cmdArgs = Environment.GetCommandLineArgs();
|
var cmdArgs = Environment.GetCommandLineArgs();
|
||||||
if (cmdArgs?.Length > 1)
|
if (cmdArgs?.Length > 1)
|
||||||
{
|
{
|
||||||
|
// Check if the last argument is a PowerToys Runner PID
|
||||||
if (int.TryParse(cmdArgs[^1], out int powerToysRunnerPid))
|
if (int.TryParse(cmdArgs[^1], out int powerToysRunnerPid))
|
||||||
{
|
{
|
||||||
RunnerHelper.WaitForPowerToysRunner(powerToysRunnerPid, () =>
|
RunnerHelper.WaitForPowerToysRunner(powerToysRunnerPid, () =>
|
||||||
@@ -107,9 +115,25 @@ namespace Peek.UI
|
|||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Command line argument is a file path - activate Peek with that file
|
||||||
|
string filePath = cmdArgs[^1];
|
||||||
|
if (File.Exists(filePath) || Directory.Exists(filePath))
|
||||||
|
{
|
||||||
|
_selectedItem = new SelectedItemByPath(filePath);
|
||||||
|
_launchedFromCli = true;
|
||||||
|
OnShowPeek();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.LogError($"Command line argument is not a valid file or directory: {filePath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeEventWaiter.WaitForEventLoop(Constants.ShowPeekEvent(), OnPeekHotkey);
|
NativeEventWaiter.WaitForEventLoop(Constants.ShowPeekEvent(), OnShowPeek);
|
||||||
NativeEventWaiter.WaitForEventLoop(Constants.TerminatePeekEvent(), () =>
|
NativeEventWaiter.WaitForEventLoop(Constants.TerminatePeekEvent(), () =>
|
||||||
{
|
{
|
||||||
ShellPreviewHandlerPreviewer.ReleaseHandlerFactories();
|
ShellPreviewHandlerPreviewer.ReleaseHandlerFactories();
|
||||||
@@ -126,11 +150,16 @@ namespace Peek.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle Peek hotkey
|
/// Handle Peek hotkey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnPeekHotkey()
|
private void OnShowPeek()
|
||||||
{
|
{
|
||||||
// Need to read the foreground HWND before activating Peek to avoid focus stealing
|
// null means explorer, not null means CLI
|
||||||
// Foreground HWND must always be Explorer or Desktop
|
if (_selectedItem == null)
|
||||||
var foregroundWindowHandle = Windows.Win32.PInvoke_PeekUI.GetForegroundWindow();
|
{
|
||||||
|
// Need to read the foreground HWND before activating Peek to avoid focus stealing
|
||||||
|
// Foreground HWND must always be Explorer or Desktop
|
||||||
|
var foregroundWindowHandle = Windows.Win32.PInvoke_PeekUI.GetForegroundWindow();
|
||||||
|
_selectedItem = new SelectedItemByWindowHandle(foregroundWindowHandle);
|
||||||
|
}
|
||||||
|
|
||||||
bool firstActivation = false;
|
bool firstActivation = false;
|
||||||
|
|
||||||
@@ -140,7 +169,38 @@ namespace Peek.UI
|
|||||||
Window = new MainWindow();
|
Window = new MainWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
Window.Toggle(firstActivation, foregroundWindowHandle);
|
Window.Toggle(firstActivation, _selectedItem, _launchedFromCli);
|
||||||
|
_launchedFromCli = false;
|
||||||
|
_selectedItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!_disposed)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
// dispose managed state (managed objects)
|
||||||
|
}
|
||||||
|
|
||||||
|
// free unmanaged resources (unmanaged objects) and override finalizer
|
||||||
|
// set large fields to null
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* // override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
|
||||||
|
// ~App()
|
||||||
|
// {
|
||||||
|
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
|
// Dispose(disposing: false);
|
||||||
|
// } */
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
|
Dispose(disposing: true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using Peek.FilePreviewer.Models;
|
|||||||
using Peek.FilePreviewer.Previewers;
|
using Peek.FilePreviewer.Previewers;
|
||||||
using Peek.UI.Extensions;
|
using Peek.UI.Extensions;
|
||||||
using Peek.UI.Helpers;
|
using Peek.UI.Helpers;
|
||||||
|
using Peek.UI.Models;
|
||||||
using Peek.UI.Telemetry.Events;
|
using Peek.UI.Telemetry.Events;
|
||||||
using Windows.Foundation;
|
using Windows.Foundation;
|
||||||
using WinUIEx;
|
using WinUIEx;
|
||||||
@@ -38,6 +39,7 @@ namespace Peek.UI
|
|||||||
/// dialog is open at a time.
|
/// dialog is open at a time.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool _isDeleteInProgress;
|
private bool _isDeleteInProgress;
|
||||||
|
private bool _exitAfterClose;
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
@@ -116,12 +118,17 @@ namespace Peek.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Toggling the window visibility and querying files when necessary.
|
/// Toggling the window visibility and querying files when necessary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Toggle(bool firstActivation, Windows.Win32.Foundation.HWND foregroundWindowHandle)
|
public void Toggle(bool firstActivation, SelectedItem selectedItem, bool exitAfterClose)
|
||||||
{
|
{
|
||||||
|
if (exitAfterClose)
|
||||||
|
{
|
||||||
|
_exitAfterClose = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (firstActivation)
|
if (firstActivation)
|
||||||
{
|
{
|
||||||
Activate();
|
Activate();
|
||||||
Initialize(foregroundWindowHandle);
|
Initialize(selectedItem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,9 +139,9 @@ namespace Peek.UI
|
|||||||
|
|
||||||
if (AppWindow.IsVisible)
|
if (AppWindow.IsVisible)
|
||||||
{
|
{
|
||||||
if (IsNewSingleSelectedItem(foregroundWindowHandle))
|
if (IsNewSingleSelectedItem(selectedItem))
|
||||||
{
|
{
|
||||||
Initialize(foregroundWindowHandle);
|
Initialize(selectedItem);
|
||||||
Activate(); // Brings existing window into focus in case it was previously minimized
|
Activate(); // Brings existing window into focus in case it was previously minimized
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -144,7 +151,7 @@ namespace Peek.UI
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Initialize(foregroundWindowHandle);
|
Initialize(selectedItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,12 +189,12 @@ namespace Peek.UI
|
|||||||
Uninitialize();
|
Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize(Windows.Win32.Foundation.HWND foregroundWindowHandle)
|
private void Initialize(SelectedItem selectedItem)
|
||||||
{
|
{
|
||||||
var bootTime = new System.Diagnostics.Stopwatch();
|
var bootTime = new System.Diagnostics.Stopwatch();
|
||||||
bootTime.Start();
|
bootTime.Start();
|
||||||
|
|
||||||
ViewModel.Initialize(foregroundWindowHandle);
|
ViewModel.Initialize(selectedItem);
|
||||||
ViewModel.ScalingFactor = this.GetMonitorScale();
|
ViewModel.ScalingFactor = this.GetMonitorScale();
|
||||||
this.Content.KeyUp += Content_KeyUp;
|
this.Content.KeyUp += Content_KeyUp;
|
||||||
|
|
||||||
@@ -207,6 +214,11 @@ namespace Peek.UI
|
|||||||
this.Content.KeyUp -= Content_KeyUp;
|
this.Content.KeyUp -= Content_KeyUp;
|
||||||
|
|
||||||
ShellPreviewHandlerPreviewer.ReleaseHandlerFactories();
|
ShellPreviewHandlerPreviewer.ReleaseHandlerFactories();
|
||||||
|
|
||||||
|
if (_exitAfterClose)
|
||||||
|
{
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -272,20 +284,11 @@ namespace Peek.UI
|
|||||||
Uninitialize();
|
Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsNewSingleSelectedItem(Windows.Win32.Foundation.HWND foregroundWindowHandle)
|
private bool IsNewSingleSelectedItem(SelectedItem selectedItem)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var selectedItems = FileExplorerHelper.GetSelectedItems(foregroundWindowHandle);
|
return selectedItem.Matches(ViewModel.CurrentItem?.Path);
|
||||||
var selectedItemsCount = selectedItems?.GetCount() ?? 0;
|
|
||||||
if (selectedItems == null || selectedItemsCount == 0 || selectedItemsCount > 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileExplorerSelectedItemPath = selectedItems.GetItemAt(0).ToIFileSystemItem().Path;
|
|
||||||
var currentItemPath = ViewModel.CurrentItem?.Path;
|
|
||||||
return fileExplorerSelectedItemPath != null && currentItemPath != null && fileExplorerSelectedItemPath != currentItemPath;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user