// 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;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using Microsoft.Plugin.WindowWalker.Properties;
using Wox.Plugin;
using Wox.Plugin.Logger;
namespace Microsoft.Plugin.WindowWalker.Components
{
internal class ContextMenuHelper
{
///
/// Returns a list of all s for the selected .
///
/// Selected result
/// List of context menu results
internal static List GetContextMenuResults(in Result result)
{
if (!(result?.ContextData is Window windowData))
{
return new List(0);
}
var contextMenu = new List()
{
new ContextMenuResult
{
AcceleratorKey = Key.F4,
AcceleratorModifiers = ModifierKeys.Control,
FontFamily = "Segoe Fluent Icons,Segoe MDL2 Assets",
Glyph = "\xE8BB", // E8B8 => Symbol: ChromeClose
Title = $"{Resources.wox_plugin_windowwalker_Close} (Ctrl+F4)",
Action = _ =>
{
if (!windowData.IsWindow)
{
Log.Debug($"Cannot close the window '{windowData.Title}' ({windowData.Hwnd}), because it doesn't exist.", typeof(ContextMenuHelper));
return false;
}
windowData.CloseThisWindow();
return !WindowWalkerSettings.Instance.OpenAfterKillAndClose;
},
},
};
// Hide menu if Explorer.exe is the shell process or the process name is ApplicationFrameHost.exe
// In the first case we would crash the windows ui and in the second case we would kill the generic process for uwp apps.
if (!windowData.Process.IsShellProcess && !(windowData.Process.IsUwpApp && string.Equals(windowData.Process.Name, "ApplicationFrameHost.exe", StringComparison.OrdinalIgnoreCase))
&& !(windowData.Process.IsFullAccessDenied && WindowWalkerSettings.Instance.HideKillProcessOnElevatedProcesses))
{
contextMenu.Add(new ContextMenuResult
{
AcceleratorKey = Key.Delete,
AcceleratorModifiers = ModifierKeys.Control,
FontFamily = "Segoe Fluent Icons,Segoe MDL2 Assets",
Glyph = "\xE74D", // E74D => Symbol: Delete
Title = $"{Resources.wox_plugin_windowwalker_Kill} (Ctrl+Delete)",
Action = _ => KillProcessCommand(windowData),
});
}
return contextMenu;
}
///
/// Method to initiate killing the process of a window
///
/// Window data
/// True if the PT Run window should close; otherwise, false.
private static bool KillProcessCommand(Window window)
{
// Validate process
if (!window.IsWindow || !window.Process.DoesExist || !window.Process.Name.Equals(WindowProcess.GetProcessNameFromProcessID(window.Process.ProcessID), StringComparison.Ordinal))
{
Log.Debug($"Cannot kill process '{window.Process.Name}' ({window.Process.ProcessID}) of the window '{window.Title}' ({window.Hwnd}), because it doesn't exist.", typeof(ContextMenuHelper));
return false;
}
// Request user confirmation
if (WindowWalkerSettings.Instance.ConfirmKillProcess)
{
string messageBody = $"{Resources.wox_plugin_windowwalker_KillMessage}\n"
+ $"{window.Process.Name} ({window.Process.ProcessID})\n\n"
+ $"{(window.Process.IsUwpApp ? Resources.wox_plugin_windowwalker_KillMessageUwp : Resources.wox_plugin_windowwalker_KillMessageQuestion)}";
MessageBoxResult messageBoxResult = MessageBox.Show(
messageBody,
Resources.wox_plugin_windowwalker_plugin_name + " - " + Resources.wox_plugin_windowwalker_KillMessageTitle,
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (messageBoxResult == MessageBoxResult.No)
{
return false;
}
}
// Kill process
window.Process.KillThisProcess(WindowWalkerSettings.Instance.KillProcessTree);
return !WindowWalkerSettings.Instance.OpenAfterKillAndClose;
}
}
}