// 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.Linq;
using Microsoft.Plugin.WindowWalker.Properties;
using Wox.Infrastructure;
using Wox.Plugin;
namespace Microsoft.Plugin.WindowWalker.Components
{
///
/// Helper class to work with results
///
internal static class ResultHelper
{
///
/// Returns a list of all results for the query.
///
/// List with all search controller matches
/// The path to the result icon
/// List of results
internal static List GetResultList(List searchControllerResults, bool isKeywordSearch, string icon, string infoIcon)
{
if (searchControllerResults == null || searchControllerResults.Count == 0)
{
return new List();
}
List resultsList = new List(searchControllerResults.Count);
bool addExplorerInfo = searchControllerResults.Any(x =>
string.Equals(x.Result.Process.Name, "explorer.exe", StringComparison.OrdinalIgnoreCase) &&
x.Result.Process.IsShellProcess);
// Process each SearchResult to convert it into a Result.
// Using parallel processing if the operation is CPU-bound and the list is large.
resultsList = searchControllerResults
.AsParallel()
.Select(x => CreateResultFromSearchResult(x, icon))
.ToList();
if (addExplorerInfo && isKeywordSearch && !WindowWalkerSettings.Instance.HideExplorerSettingInfo)
{
resultsList.Add(GetExplorerInfoResult(infoIcon));
}
return resultsList;
}
///
/// Creates a Result object from a given SearchResult.
///
/// The SearchResult object to convert.
/// The path to the icon that should be used for the Result.
/// A Result object populated with data from the SearchResult.
private static Result CreateResultFromSearchResult(SearchResult searchResult, string icon)
{
return new Result
{
Title = searchResult.Result.Title,
IcoPath = icon,
SubTitle = GetSubtitle(searchResult.Result),
ContextData = searchResult.Result,
Action = c =>
{
searchResult.Result.SwitchToWindow();
return true;
},
Score = searchResult.Score,
// For debugging you can set the second parameter to true to see more information.
ToolTipData = GetToolTip(searchResult.Result, false),
};
}
///
/// Returns the subtitle for a result
///
/// The window properties of the result
/// String with the subtitle
private static string GetSubtitle(Window window)
{
if (window == null || !(window is Window))
{
return string.Empty;
}
string subtitleText = Resources.wox_plugin_windowwalker_Running + ": " + window.Process.Name;
if (WindowWalkerSettings.Instance.SubtitleShowPid)
{
subtitleText += $" ({window.Process.ProcessID})";
}
if (!window.Process.IsResponding)
{
subtitleText += $" [{Resources.wox_plugin_windowwalker_NotResponding}]";
}
if (WindowWalkerSettings.Instance.SubtitleShowDesktopName && Main.VirtualDesktopHelperInstance.GetDesktopCount() > 1)
{
subtitleText += $" - {Resources.wox_plugin_windowwalker_Desktop}: {window.Desktop.Name}";
}
return subtitleText;
}
///
/// Returns the tool tip for a result
///
/// The window properties of the result
/// Value indicating if a detailed debug tooltip should be returned
/// Tooltip for the result or null of failure
private static ToolTipData GetToolTip(Window window, bool debugToolTip)
{
if (window == null || !(window is Window))
{
return null;
}
if (!debugToolTip)
{
string text = $"{Resources.wox_plugin_windowwalker_Process}: {window.Process.Name}";
text += $"\n{Resources.wox_plugin_windowwalker_ProcessId}: {window.Process.ProcessID}";
if (Main.VirtualDesktopHelperInstance.GetDesktopCount() > 1)
{
text += $"\n{Resources.wox_plugin_windowwalker_Desktop}: {window.Desktop.Name}";
if (!window.Desktop.IsAllDesktopsView)
{
text += $" ({Resources.wox_plugin_windowwalker_Number} {window.Desktop.Number})";
}
}
return new ToolTipData(window.Title, text);
}
else
{
string text = $"hWnd: {window.Hwnd}\n" +
$"Window class: {window.ClassName}\n" +
$"Process ID: {window.Process.ProcessID}\n" +
$"Thread ID: {window.Process.ThreadID}\n" +
$"Process: {window.Process.Name}\n" +
$"Process exists: {window.Process.DoesExist}\n" +
$"Is full access denied: {window.Process.IsFullAccessDenied}\n" +
$"Is uwp app: {window.Process.IsUwpApp}\n" +
$"Is ShellProcess: {window.Process.IsShellProcess}\n" +
$"Is window cloaked: {window.IsCloaked}\n" +
$"Window cloak state: {window.GetWindowCloakState()}\n" +
$"Desktop id: {window.Desktop.Id}\n" +
$"Desktop name: {window.Desktop.Name}\n" +
$"Desktop number: {window.Desktop.Number}\n" +
$"Desktop is visible: {window.Desktop.IsVisible}\n" +
$"Desktop position: {window.Desktop.Position}\n" +
$"Is AllDesktops view: {window.Desktop.IsAllDesktopsView}\n" +
$"Responding: {window.Process.IsResponding}";
return new ToolTipData(window.Title, text);
}
}
///
/// Returns an information result about the explorer setting
///
/// The path to the info icon.
/// An object of the type with the information.
private static Result GetExplorerInfoResult(string iIcon)
{
return new Result()
{
Title = Resources.wox_plugin_windowwalker_ExplorerInfoTitle,
IcoPath = iIcon,
SubTitle = Resources.wox_plugin_windowwalker_ExplorerInfoSubTitle,
Action = c =>
{
Helper.OpenInShell("rundll32.exe", "shell32.dll,Options_RunDLL 7"); // "shell32.dll,Options_RunDLL 7" opens the view tab in folder options of explorer.
return true;
},
Score = 100_000,
};
}
}
}